Multithreading 使用条件_变量时不同的互斥锁行为

Multithreading 使用条件_变量时不同的互斥锁行为,multithreading,mutex,condition-variable,Multithreading,Mutex,Condition Variable,我在两种不同的情况下使用互斥: -第一个示例:我使用具有唯一_锁的互斥锁来确保线程不会同时访问同一资源 -第二个示例:我扩展了我的第一个示例以使用一个condition_变量,这样所有线程都会等待,直到这个额外的线程通知它们 这是我的第一个例子 #include <thread> #include <mutex> #include <condition_variable> #include <iostream> using namespace s

我在两种不同的情况下使用互斥: -第一个示例:我使用具有唯一_锁的互斥锁来确保线程不会同时访问同一资源 -第二个示例:我扩展了我的第一个示例以使用一个condition_变量,这样所有线程都会等待,直到这个额外的线程通知它们

这是我的第一个例子

#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>

using namespace std;

mutex               Mutex;
condition_variable  cv;
bool                ready = false;

void print(const char* ThreadName,int WaitTime)
{
    cout << ThreadName << " : Waiting to get lock!" << endl;
    unique_lock<mutex> lock(Mutex);
    cout << ThreadName << " : Got the lock" << endl;
    this_thread::sleep_for(chrono::milliseconds(WaitTime));
    while (!ready)
    {
        cv.wait(lock);
    }
    cout<< ThreadName << " : thread is finishing now...." << endl;
}

void execute(const char* ThreadName)
{
    this_thread::sleep_for(chrono::milliseconds(2000));
    cout<< ThreadName << "Thready is ready to be executed!" << endl;
    ready = true;
    cv.notify_all();
}

int main()
{
    thread t1(print, "Print1",200);
    thread t2(print, "Print2",1000);
    thread t3(print, "Print3",500);
    thread t4(print, "Print4",10);
    thread te(execute, "Execute");

    t1.join();
    t2.join();
    t3.join();
    t4.join();
    te.join();

    return 0;
}
我们可以看到,获得互斥锁的第一个线程可以完成他的任务,并且只有在完成后,下一个线程才能超越unique_lock(互斥锁)语句

现在,我扩展这个示例以使用条件变量

#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>

using namespace std;

mutex               Mutex;
condition_variable  cv;
bool                ready = false;

void print(const char* ThreadName,int WaitTime)
{
    cout << ThreadName << " : Waiting to get lock!" << endl;
    unique_lock<mutex> lock(Mutex);
    cout << ThreadName << " : Got the lock" << endl;
    this_thread::sleep_for(chrono::milliseconds(WaitTime));
    while (!ready)
    {
        cv.wait(lock);
    }
    cout<< ThreadName << " : thread is finishing now...." << endl;
}

void execute(const char* ThreadName)
{
    this_thread::sleep_for(chrono::milliseconds(2000));
    cout<< ThreadName << "Thready is ready to be executed!" << endl;
    ready = true;
    cv.notify_all();
}

int main()
{
    thread t1(print, "Print1",200);
    thread t2(print, "Print2",1000);
    thread t3(print, "Print3",500);
    thread t4(print, "Print4",10);
    thread te(execute, "Execute");

    t1.join();
    t2.join();
    t3.join();
    t4.join();
    te.join();

    return 0;
}
我不明白的是,当condition_变量和互斥体之间没有任何链接时,所有4个线程如何能够锁定互斥体

…当条件_变量和互斥锁之间没有链接时

链接如下:

cv.wait(lock);
wait
函数在返回前执行三项操作:

  • 它解锁给定的
  • 它等待其他线程调用
    cv.notify_all()
    ,然后
  • 它重新锁定

  • 当然,如果其他线程首先被唤醒,那么它可能需要等待从通知中唤醒后重新锁定锁。

    上面的两个示例具有相同的代码。
    Print1Print3: Waiting to get lock!
    : Waiting to get lock!
    Print2 : Waiting to get lock!
    Print4 : Waiting to get lock!
    Print3 : Got the lock
    Print1 : Got the lock
    Print4 : Got the lock
    Print2 : Got the lock
    ExecuteThready is ready to be executed!
    Print2 : thread is finishing now....
    Print4 : thread is finishing now....
    Print1 : thread is finishing now....
    Print3 : thread is finishing now....
    
    cv.wait(lock);