生产者消费者的第一个版本
std::deque<int> q;
std::mutex mu;
void function_1(LogFile& log)
{
int count = 10;
while (count > 0) {
std::unique_lock<mutex> locker(mu);
q.push_front(count);
locker.unlock();
std::this_thread::sleep_for(chrono::seconds(1));
count--;
}
}
void function_2() {
int data = 0;
while (data != 1) {
std::unique_lock<mutex> locker(mu);
if (!q.empty()) {
data = q.back();
q.pop_back();
locker.unlock();
cout << "t2 got a value from t1: " << data << endl;
}
else {
locker.unlock();
}
}
}
这个版本的问题是消费者会一直抢锁,需要增加一个sleep.改成下面的版本
std::deque<int> q;
std::mutex mu;
void function_1(LogFile& log)
{
int count = 10;
while (count > 0) {
std::unique_lock<mutex> locker(mu);
q.push_front(count);
locker.unlock();
std::this_thread::sleep_for(chrono::seconds(1));
count--;
}
}
void function_2() {
int data = 0;
while (data != 1) {
std::unique_lock<mutex> locker(mu);
if (!q.empty()) {
data = q.back();
q.pop_back();
locker.unlock();
cout << "t2 got a value from t1: " << data << endl;
}
else {
locker.unlock();
std::this_thread::sleep_for(chrono::seconds(10));
}
}
}
第二个版本的问题是睡眠时间不是最优的.这里就需要condition variable了
std::deque<int> q;
std::mutex mu;
std::condition_variable cond;
void function_1()
{
int count = 10;
while (count > 0) {
std::unique_lock<mutex> locker(mu);
q.push_front(count);
cout << "t1 push a value : " << count << endl;
locker.unlock();
cond.notify_one();//Notify one waiting thread, if there is one.
std::this_thread::sleep_for(chrono::seconds(1));
count--;
}
cout << "t1 exit : " << endl;
}
void function_2() {
int data = 0;
while (data != 1) {
std::unique_lock<mutex> locker(mu);
cond.wait(locker);
data = q.back();
q.pop_back();
locker.unlock();
cout << "t2 got a value from t1: " << data << endl;
}
cout << "t2 exit : " << endl;
}
上面这个condtion variable版本, 消费者有可能没有接到提醒,所以改成下面这个版本
std::deque<int> q;
std::mutex mu;
std::condition_variable cond;
void function_1()
{
int count = 10;
while (count > 0) {
std::unique_lock<mutex> locker(mu);
q.push_front(count);
cout << "t1 push a value : " << count << endl;
locker.unlock();
cond.notify_one();//Notify one waiting thread, if there is one.
std::this_thread::sleep_for(chrono::seconds(1));
count--;
}
cout << "t1 exit : " << endl;
}
void function_2() {
int data = 0;
while (data != 1) {
std::unique_lock<mutex> locker(mu);
cond.wait(locker, []() {return !q.empty(); });
data = q.back();
q.pop_back();
locker.unlock();
cout << "t2 got a value from t1: " << data << endl;
}
cout << "t2 exit : " << endl;
}
这个版本消费者会自己醒来看看是否满足条件,如果满足条件,则运行.STL真是太牛逼了.如果线程多了,可以用cond.notify_all() 来唤醒所有等待线程.