C++11中的条件变量支持把判断条件写到参数里。配合lamda表达式让程序代码更加清晰。第一个参数只支持unique_lock他和lock_guard的区别在于可以在作用域内加锁再解锁,而lock_gurad只能在构造和析构的时候加锁和解锁。
下面是对cv的小应用,轮流打印AB
#include <thread>
#include <iostream>
#include <mutex>
#include <condition_variable>
using namespace std;
mutex m;
condition_variable cv;
bool flag = true;
void printA()
{
while(1)
{
unique_lock<mutex>ul(m);
cv.wait(ul,[]{return flag;});
cout<<"A"<<endl;
flag=false;
cv.notify_one();
}
}
void printB()
{
while(1)
{
unique_lock<mutex>ul(m);
cv.wait(ul,[]{return !flag;});
cout<<"B"<<endl;
flag=true;
cv.notify_one();
}
}
int main()
{
std::thread tA(printA);
std::thread tB(printB);
tA.join();
tB.join();
return 0;
}
再附一个简单的线程安全队列模型
#include <thread>
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <queue>
using namespace std;
struct Task
{
Task(thread::id p,int i):pro(p),index(i)
{ }
thread::id pro;
int index;
};
class Safequeue
{
private:
mutex _m;
condition_variable _cv;
queue<Task>_q;
public:
void insert(Task x)
{
unique_lock<mutex>ul(_m);
_q.push(x);
_cv.notify_one();
}
Task take()
{
unique_lock<mutex>ul(_m);
_cv.wait(ul,[this]{return !_q.empty();});
Task task=_q.front();
_q.pop();
return task;
}
};
Safequeue taskqueue;
void troublemaker()
{
int c=0;
while(1)
{
_sleep(1000);
taskqueue.insert(Task(this_thread::get_id(),c++));
}
}
void worker()
{
while(1)
{
Task task=taskqueue.take();
cout<<this_thread::get_id()<<" get "<<task.index<<" from "<<task.pro<<endl;
}
}
int main()
{
thread t1(troublemaker);
thread t2(troublemaker);
thread w1(worker);
thread w2(worker);
t1.join();
t2.join();
w1.join();
w2.join();
}