为什么这个条件变量不起作用?

时间:2019-07-19 06:45:41

标签: c++ multithreading

我试图了解C ++标准中可用的condition_variable。因此,在下面编写的测试代码中,我希望func1在主线程中打印50个数字后被唤醒,但是在这里它仅打印主线程中的所有数字吗?

能否请您在这里帮助我更好地了解condition_variable,以表明有特定的线程需要唤醒

我尝试使用以下代码了解条件变量:

#include <stdio.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

using namespace std;
std::mutex mu;
std::condition_variable multiple;
bool isLoaded = false;

void func1()
{
    std::unique_lock<std::mutex> unLock(mu);
    multiple.wait(unLock, []() {return isLoaded; });
    for (int i = 0; i < 100; i++)
    {        
        cout << "This is from thread; " << i << endl;                
    }
}

int main()
{
    std::thread t1(func1);
    std::lock_guard<std::mutex> gaurd(mu);

    cout << std::thread::hardware_concurrency()<< endl;

    for (int i = 0; i < 100; i++)
    {
        if (i == 50)
        {
            isLoaded = true;
            multiple.notify_one();
            std::this_thread::sleep_for(std::chrono::seconds(4));
        }
        cout << "This is from main; " << i << endl;
    }

    t1.join();
    getchar();
    return 0;
}

2 个答案:

答案 0 :(得分:5)

您永远不会在主线程中释放mu。尝试这样的事情:

int main()
{
    std::thread t1(func1);

    cout << std::thread::hardware_concurrency()<< endl;

    for (int i = 0; i < 100; i++)
    {
        if (i == 50)
        {
            {
                std::lock_guard<std::mutex> gaurd(mu);
                isLoaded = true;
            }
            multiple.notify_one();
            std::this_thread::sleep_for(std::chrono::seconds(4));
        }
        cout << "This is from main; " << i << endl;
    }

    t1.join();
    getchar();
    return 0;
}

通常,您需要在尽可能短的时间内保持锁。

答案 1 :(得分:3)

您正在程序启动时使用互斥锁mu,并且永远不要放开它,因此该互斥锁下的任何其他代码都将永远不会执行。

相反,您仅应在更改共享变量时保留它,例如:

    {
        std::lock_guard<std::mutex> gaurd(mu);
        isLoaded = true;
        multiple.notify_one();
    }