PoEdu培训 Windows班 第二十七课 Windows 线程(八) 线程上下文和线程加锁
文章类别: 培训笔记 0 评论

PoEdu培训 Windows班 第二十七课 Windows 线程(八) 线程上下文和线程加锁

文章类别: 培训笔记 0 评论

Windows 线程(八) 线程上下文和线程加锁

CONTEXT(线程运行上下文)

可以使用GetThreadContextAPI来获取线程的上下文

// 获取线程上下文的例子
#include <Windows.h>
#include <process.h>
#include <tchar.h>
#include <iostream>

BOOL bLock = FALSE;        // 一把简单的锁 标识printf已经执行完成

UINT WINAPI ThreadRun(LPVOID lParam)
{
    INT nNum = 0;
    while (TRUE)
    {
        if (!bLock)
        {
            bLock = TRUE;    // 相当于加锁
            _tprintf(TEXT("ThreadRun.....[%d]\n"), nNum++);    // 这个函数是非线程安全的
            bLock = FALSE;    // 解锁
        }
    }
    return 0;
}

UINT WINAPI ThreadMonitor(LPVOID lParam)
{
    HANDLE hThread = (HANDLE)lParam;
    while (TRUE)
    {
        CONTEXT context;
        context.ContextFlags = CONTEXT_ALL;
        SuspendThread(hThread);        // 挂起ThreadRun
        GetThreadContext(hThread, &context);    // 获取ThreadRun的上下文
        if (!bLock)
        {
            bLock = TRUE;    // 加锁
            _tprintf(TEXT("EAX:[0x%x] ESP:[0x%x] EIP:[0x%x]\n"),    // 打印
                context.Eax, context.Esp, context.Eip);
            bLock = FALSE;    // 解锁
        }
        ResumeThread(hThread);        // 恢复ThreadRun
    }
    return 0;
}

int main()
{
    _tsetlocale(LC_ALL, TEXT(""));
    HANDLE hThreads[2];
    hThreads[0] = (HANDLE)_beginthreadex(NULL, 0, ThreadRun, NULL, 0, NULL);
    hThreads[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadMonitor, hThreads[0], 0, NULL);

    WaitForMultipleObjects(sizeof(hThreads) / sizeof(HANDLE), hThreads, TRUE, INFINITE);
    
    for (size_t i = 0; i < sizeof(hThreads) / sizeof(HANDLE); ++i)
    {
        CloseHandle(hThreads[i]);
    }
    return 0;
}

线程安全和上锁

在上面的小例子中, 我们使用了一个"简单的锁功能"
通过这个简单的锁, 我们将非线程安全的函数变得相对"安全"
通过锁还可以保证数据的正确性

未完待续...

如有错误,请提出指正!谢谢.

回复