【问题标题】:Different mutex lock behaviour when using a condition_variable使用 condition_variable 时的不同互斥锁行为
【发布时间】:2020-08-12 07:52:22
【问题描述】:

我在两种不同的情况下使用互斥锁: - 第一个示例:我使用带 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;
}

这样的结果是:

Print1Print3 : Waiting to get lock!Print2 : Waiting to get lock!
Print2 : Got the lock

Print4 : Waiting to get lock!
 : Waiting to get lock!
Print2 : thread is finishing now....
Print3 : Got the lock
Print3 : thread is finishing now....
Print4 : Got the lock
Print4 : thread is finishing now....
Print1 : Got the lock
Print1 : thread is finishing now....

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

现在我扩展此示例以使用条件变量

#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;
}

这个输出是

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....

我不明白的是,所有 4 个线程如何都可以锁定互斥锁,而条件变量和互斥锁之间没有链接?

【问题讨论】:

  • 你上面的两个例子有相同的代码。

标签: multithreading mutex condition-variable


【解决方案1】:

...当条件变量和互斥体之间没有任何联系时?

链接在这里:

cv.wait(lock);

wait 函数在返回之前做了三件事:

  1. 解锁给定的lock
  2. 它等待某个其他线程调用cv.notify_all(),然后
  3. 它会重新锁定lock

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多