PoEdu培训 Windows班 第二十一课 Windows线程(二) 线程时间片
文章类别: 培训笔记 0 评论

PoEdu培训 Windows班 第二十一课 Windows线程(二) 线程时间片

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

Windows 线程(二) 时间片

深入理解时间片

线程的执行顺序

我们启动两个线程
在第一个线程中打印 1--100
在第二个线程中打印 101--200
在主线程中打印 201--300
那么他们的执行结果会是什么样的呢?
我们写一个小例子:

#include <Windows.h>
#include <tchar.h>
#include <iostream>

DWORD WINAPI ThreadMainNo1(LPVOID lParam)
{
    for (size_t i = 0; i < 101; i++)
    {
        _tprintf(TEXT("ThreadNo1: [%d]\n"), i);
    }
    return 0;
}

DWORD WINAPI ThreadMainNo2(LPVOID lParam)
{
    for (size_t i = 101; i < 201; i++)
    {
        _tprintf(TEXT("ThreadNo2: [%d]\n"), i);
    }
    return 0;
}

INT _tmain()
{
    _tsetlocale(LC_ALL, TEXT(""));

    HANDLE hThreads[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };

    hThreads[0] = CreateThread(NULL, 0, ThreadMainNo1, NULL, 0, NULL);
    hThreads[1] = CreateThread(NULL, 0, ThreadMainNo2, NULL, 0, NULL);

    for (size_t i = 201; i < 301; i++)
    {
        _tprintf(TEXT("ThreadNo3: [%d]\n"), i);
    }

    WaitForMultipleObjects(2, hThreads, TRUE, INFINITE);

    return 0;
}

那么执行结果呢?
如下图:
Alt 执行结果

可以知道, 我们的线程是抢占式运行的, 线程的执行顺序_未知_

线程执行顺序的控制

通过 Sleep, WaitForSingleObject 等等阻塞函数可以使线程挂起, 让出时间片
但是这种方法会让线程的执行顺序更加混乱

我们可以通过信号控制来进行控制

我们来改造一下代码, 使得线程按照 1, 2, 3 的顺序进行执行

#include <Windows.h>
#include <tchar.h>
#include <iostream>

enum ThreadSignal
{
    THREAD_NO_0,
    THREAD_NO_1,
    THREAD_NO_2,
    THREAD_NO_3
};

ThreadSignal g_ThreadSignal = THREAD_NO_0;

DWORD WINAPI ThreadMainNo1(LPVOID lParam)
{
    for (size_t i = 0; i < 101; i++)
    {
        while (g_ThreadSignal != THREAD_NO_1)
        {
            Sleep(1);
        }
        _tprintf(TEXT("ThreadNo1: [%d]\n"), i);
        // 希望NO2执行
        g_ThreadSignal = THREAD_NO_2;
    }
    return 0;
}

DWORD WINAPI ThreadMainNo2(LPVOID lParam)
{
    for (size_t i = 101; i < 201; i++)
    {
        while (g_ThreadSignal != THREAD_NO_2)
        {
            Sleep(1);
        }
        _tprintf(TEXT("ThreadNo2: [%d]\n"), i);
        // 希望NO3执行
        g_ThreadSignal = THREAD_NO_3;
    }
    return 0;
}

INT _tmain()
{
    _tsetlocale(LC_ALL, TEXT(""));

    HANDLE hThreads[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };

    hThreads[0] = CreateThread(NULL, 0, ThreadMainNo1, NULL, 0, NULL);
    hThreads[1] = CreateThread(NULL, 0, ThreadMainNo2, NULL, 0, NULL);

    g_ThreadSignal = THREAD_NO_1;

    for (size_t i = 201; i < 301; i++)
    {
        while (g_ThreadSignal != THREAD_NO_3)
        {
            Sleep(1);
        }
        _tprintf(TEXT("ThreadNo3: [%d]\n"), i);
        // 希望NO1执行
        g_ThreadSignal = THREAD_NO_1;
    }

    WaitForMultipleObjects(2, hThreads, TRUE, INFINITE);

    return 0;
}

我们看一下执行结果:
Alt 执行结果

所以, 如果我们想要控制线程的执行顺序, 可以通过"线程信号"这样类似的方式来控制

未完待续...

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

回复