一、条件变量condition_variable、wait()、notify_one()
1)condition_variable
- std::condition_variable实际使用一个类,是一个和条件相关的一个类,说白了就是等待一个条件达成,这个类需要和互斥量来配合工作
2)wait()
#include<iostream>
#include<thread>
#include<string>
#include<vector>
#include<list>
#include<mutex>
using namespace std;
class example {
public:
void messagein() {
for (int i = 0; i < 10000; i++)
{
unique_lock<mutex>guard(mymutex);
cout << "messagein(),服务器收集数据数量:" << i << endl;
num.push_back(i);
}
return;
}
void messageout() {
int command = 0;
while (true)
{
std::unique_lock<mutex>guard(mymutex);
mycond.wait(guard, [this] {
if (!num.empty()) {
return true;
}
return false;
});
}
}
private:
list<int>num;
mutex mymutex;
condition_variable mycond;
};
int main() {
example ex;
thread out(&example::messageout, &ex);
thread in(&example::messagein, &ex);
out.join();
in.join();
cout << "主线程运行" << endl;
system("pause");
return 0;
}
-
wait()函数参数的讲解以及用法: -
1、如果第二个参数lambda表达式返回值是true,那么wait()直接返回,继续执行下面的代码 -
2、如果第二个参数lambda表达式返回值是false,那么wait()将解锁互斥量,并阻塞到本行,那阻塞到什么时候呢?阻塞到其他某个线程调用notify_one()成员函数为止 -
3、如果没有第二个参数,代码中mycond.wait(guard)那么就跟第二个参数lambda表达式返回false效果一样,wait()将解锁互斥量,并阻塞到本行,阻塞到其他某个线程调用notify_one()成员函数为止 -
4、当其他线程用notify_one()将本wait(原来是阻塞/堵塞)的状态唤醒后,wait就开始恢复干活,恢复后wait干什么
- a):wait()不断的尝试重新获取互斥量,如果获取不到,那么流程就卡在wait这里等着获取,如果获取到了锁(等于加了锁),那么wait就继续执行b)
- b):
- b.1)如果wait有第二个参数(lambda),就判断这个lambda表达式,如果lambda表达式为false,那么wait又对互斥量解锁,然后又休眠这里等待再次被notify_one()唤醒
- b.2)如果lambda表达式为true,则wait返回,流程走下来(此时互斥量被锁着)
- b.3)如果wait没有第二个参数,则wait返回,流程走下来
3)notify_one()
class example {
public:
void messagein() {
for (int i = 0; i < 10000; i++)
{
unique_lock<mutex>guard(mymutex);
cout << "messagein(),服务器收集数据数量:" << i << endl;
num.push_back(i);
mycond.notify_one();
}
return;
}
void messageout() {
int command = 0;
while (true)
{
std::unique_lock<mutex>guard(mymutex);
mycond.wait(guard, [this] {
if (!num.empty()) {
return true;
}
return false;
});
command = num.front();
num.pop_front();
cout << "messageout()执行,取出一个元素:" << command <<",thread_id:"<<this_thread::get_id()<< endl;
guard.unlock();
}
}
private:
list<int>num;
mutex mymutex;
condition_variable mycond;
};
二、notify_one()与notify_all()区别
-
notify_one():通知一个线程的wait() -
notify_all():通知所有线程的wait() 当有多个线程使用wait()时,notify_one()一个一个这样唤醒会影响运行效率,因此notify_all()会比notify_one()好用
#include<iostream>
#include<thread>
#include<string>
#include<vector>
#include<list>
#include<mutex>
using namespace std;
class example {
public:
void messagein() {
for (int i = 0; i < 10000; i++)
{
unique_lock<mutex>guard(mymutex);
cout << "messagein(),服务器收集数据数量:" << i << endl;
num.push_back(i);
mycond.notify_all();
}
return;
}
void messageout() {
int command = 0;
while (true)
{
std::unique_lock<mutex>guard(mymutex);
mycond.wait(guard, [this] {
if (!num.empty()) {
return true;
}
return false;
});
command = num.front();
num.pop_front();
cout << "messageout()执行,取出一个元素:" << command <<",thread_id:"<<this_thread::get_id()<< endl;
guard.unlock();
}
}
private:
list<int>num;
mutex mymutex;
condition_variable mycond;
};
int main() {
example ex;
thread out(&example::messageout, &ex);
thread out1(&example::messageout, &ex);
thread in(&example::messagein, &ex);
out.join();
out1.join();
in.join();
cout << "主线程运行" << endl;
system("pause");
return 0;
}
|