c++ - 如何让它同步运行?

标签 c++ windows multithreading winapi c++98

你好,我想同步两个线程,一个递增一个变量,另一个递减它。 我想要的结果如下所示:

线程 #0 j = 1

线程 #1 j = 0

线程 #0 j = 1

线程 #1 j = 0

等等......但我的代码有时会这样工作,在某些情况下它会打印出非常奇怪的值。我想我在某处有一些未定义的行为,但我无法弄清楚到底发生了什么。

我的代码包含在一个 HANDLE ghMutex 中,其中包含我的互斥锁的处理程序:

我的主要功能:

int main(void)
{
    HANDLE aThread[THREADCOUNT];

    ghMutex = CreateMutex(NULL, FALSE, NULL);             

    aThread[0] = (HANDLE)_beginthreadex(NULL, 0, &inc, NULL, CREATE_SUSPENDED, 0);
    aThread[1] = (HANDLE)_beginthreadex(NULL, 0, &dec, NULL, CREATE_SUSPENDED, 0);

    ResumeThread(aThread[0]);
    ResumeThread(aThread[1]);

    WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);

    printf("j = %d\n", j);

    for (int i = 0; i < THREADCOUNT; i++)
        CloseHandle(aThread[i]);

    CloseHandle(ghMutex);

    return 0;
}

公司功能:

unsigned int __stdcall inc(LPVOID)
{
    for (volatile int i = 0; i < MAX; ++i)
    {
        WaitForSingleObject(
            ghMutex,    // handle to mutex
            INFINITE);  // no time-out interval

            j++;
            printf("Thread %d j = %d\n", GetCurrentThreadId(), j);
            ReleaseMutex(ghMutex);

    }
    _endthread();

    return TRUE;
}

dec函数:

unsigned int __stdcall dec(void*)
{
    for (volatile int i = 0; i < MAX; ++i)
    {
        WaitForSingleObject(
            ghMutex,    // handle to mutex
            INFINITE);  // no time-out interval

        j--;
        printf("Thread %d j = %d\n", GetCurrentThreadId(), j);
        ReleaseMutex(ghMutex);
    }
    _endthread();

    return TRUE;
}

我需要一个 std c++98 中的 win api 解决方案。

最佳答案

互斥锁不是同步两个线程的正确工具,它是用来保护资源的。您确实有一个受互斥体保护的资源 j,但是未定义哪个线程获得锁的顺序,因此您可以遇到 dec 被多次调用的情况inc 有机会运行之前的次数。

如果你想同步线程的顺序,你将不得不使用另一个同步原语,例如信号量。例如,您可以在 inc 中递增信号量并在 dec 中递减它。这将是经典的生产者 - 消费者关系,当信号量达到其最大值时,生产者将停止,而消费者将等待项目消费。

抱歉,我没有提供 WinAPI C++98 解决方案,因为这很愚蠢,但我希望我为您指明了正确的方向。

关于c++ - 如何让它同步运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58159892/

相关文章:

multithreading - 是否有任何领域应该优先考虑线程而不是协程?

c++ - 使用 OpenCV 进行手部检测

regex - 为什么这个正则表达式匹配返回一个 HashMap ?

c++ - InterlockedIncrement 与 EnterCriticalSection/counter++/LeaveCriticalSection

java - 在Java进程上调用Windows10计算器?

windows - 尽管使用双引号和转义符,Windows 上的 AWS CLI 仍无法工作

java - 即使线程关闭后, Activity 线程计数也不会减少

c++ - std::thread() 和 std::ref() 在类内部使用时导致构建错误

c++ - 使用 ATL CImage 从内存缓冲区加载图像

c++ - 如何导出模板函数的输出类型?