使用 condition_variable 时不同的互斥锁行为
Different mutex lock behaviour when using a condition_variable
我在两种不同的情况下使用互斥量:
- 第一个示例:我将互斥体与 unique_lock 一起使用,以确保线程不会同时访问同一资源
- 第二个示例:我将第一个示例扩展为使用 condition_variable,以便所有线程等待直到这个附加线程通知它们。
这是我的第一个例子
#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 锁( Mutex); 语句
现在我将此示例扩展为使用 condition_variable
#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 个线程都可以锁定互斥锁,而 condition_variable 和互斥锁之间没有 link?
...when there is nowhere a link between the condition_variable and the mutex?
link 在这里:
cv.wait(lock);
wait
函数在它之前做了三件事 returns:
- 它解锁给定的
lock
,
- 它等待其他线程调用
cv.notify_all()
,然后
- 它重新锁定
lock
。
当然,如果有其他线程先被唤醒,那么它可能要等到通知唤醒后再重新加锁。
我在两种不同的情况下使用互斥量: - 第一个示例:我将互斥体与 unique_lock 一起使用,以确保线程不会同时访问同一资源 - 第二个示例:我将第一个示例扩展为使用 condition_variable,以便所有线程等待直到这个附加线程通知它们。
这是我的第一个例子
#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 锁( Mutex); 语句
现在我将此示例扩展为使用 condition_variable
#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 个线程都可以锁定互斥锁,而 condition_variable 和互斥锁之间没有 link?
...when there is nowhere a link between the condition_variable and the mutex?
link 在这里:
cv.wait(lock);
wait
函数在它之前做了三件事 returns:
- 它解锁给定的
lock
, - 它等待其他线程调用
cv.notify_all()
,然后 - 它重新锁定
lock
。
当然,如果有其他线程先被唤醒,那么它可能要等到通知唤醒后再重新加锁。