一、condition_variable
// 当前线程的执行会被阻塞,直到收到 notify 为止。
void wait (unique_lock<mutex>& lck);
// 当前线程仅在pred=false时阻塞;如果pred=true时,不阻塞。
template <class Predicate>
void wait (unique_lock<mutex>& lck, Predicate pred);
// Unblocks当前正在等待此条件的一个线程。
// 如果没有线程在等待,则函数不执行任何操作。
// 如果有多个线程在等待,它不会指定具体哪个线程。
void notify_one() noexcept;
// Unblocks当前等待此条件的所有线程。
// 如果没有线程在等待,则函数不执行任何操作。
void notify_all() noexcept;
C++多线程04:condition_variable(条件变量)_CHANG_THE_WORLD的博客-CSDN博客
二、奇偶数
创建两个线程,一个打印奇数,一个打印偶数。采用互斥锁(共享资源)+条件变量(唤醒线程)实现。
可以使用一个条件变量或者连个条件变量实现。
#include<iostream>
#include<condition_variable>
#include <mutex>
#include <thread>
std::mutex data_mutex;
std::condition_variable data_var;
std::mutex mut;
std::condition_variable cond1,cond2;
int num=100,g_nums=1;
//双条件变量版本
void thread1() {
while (true) {
std::unique_lock<std::mutex> locker(mut); //会自动解锁
if (g_nums % 2 == 1 && g_nums <= num)
{
std::cout << "Thread1:" << g_nums << std::endl;
g_nums++;
}
cond2.notify_one();
cond1.wait(locker);
if (g_nums >= num+1)
break;
}
std::cout << "thread1 done"<< std::endl;
cond2.notify_one();
}
void thread2() {
while (true) {
std::unique_lock<std::mutex> locker(mut);
if (g_nums % 2 == 0 && g_nums <= num)
{
std::cout << "Thread2:" << g_nums << std::endl;
g_nums++;
}
cond1.notify_one();
cond2.wait(locker);
if (g_nums >= num + 1)
break;
}
std::cout << "thread2 done" << std::endl;
cond1.notify_one();
}
int main() {
std::thread t1(thread1);
std::thread t2(thread2);
t1.join();
t2.join();
return 0;
}
#include<iostream>
#include<condition_variable>
#include <mutex>
#include <thread>
std::mutex data_mutex;
std::condition_variable data_var;
std::mutex mut;
std::condition_variable cond;
int num=100,g_nums=1;
//单条件变量版本
void thread1() {
while (true) {
std::unique_lock<std::mutex> locker(mut); //会自动解锁
if (g_nums % 2 == 1 && g_nums <= num)
{
std::cout << "Thread1:" << g_nums << std::endl;
g_nums++;
}
cond.notify_one();//唤醒另外的一个进程
cond.wait(locker);//阻塞当前进程
if (g_nums >= num+1)
break;
}
std::cout << "thread1 done"<< std::endl;
cond.notify_one();
}
void thread2() {
while (true) {
std::unique_lock<std::mutex> locker(mut);
if (g_nums % 2 == 0 && g_nums <= num)
{
std::cout << "Thread2:" << g_nums << std::endl;
g_nums++;
}
cond.notify_one();//唤醒另外一个进程
cond.wait(locker);
if (g_nums >= num + 1)
break;
}
std::cout << "thread2 done" << std::endl;
cond.notify_one();
}
int main() {
std::thread t1(thread1);
std::thread t2(thread2);
t1.join();
t2.join();
return 0;
}
三、循环打印AB
注意wait有两种使用方式,参考:C++多线程04:condition_variable(条件变量)_CHANG_THE_WORLD的博客-CSDN博客
#include<iostream>
#include<condition_variable>
#include <mutex>
#include <thread>
std::mutex data_mutex;
std::condition_variable data_var;
bool flag = true;//通过flag决定两个线程是否阻塞
void printA()
{
while(1)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lck(data_mutex) ;
data_var.wait(lck,[]{return flag;});//false才阻塞,true不阻塞
std::cout<<"thread: "<< std::this_thread::get_id() << " printf: " << "A" <<std::endl;
flag = false;
data_var.notify_one();
}
}
void printB()
{
while(1)
{
std::unique_lock<std::mutex> lck(data_mutex) ;
data_var.wait(lck,[]{return !flag;});
std::cout<<"thread: "<< std::this_thread::get_id() << " printf: " << "B" <<std::endl;
flag = true;
data_var.notify_one();
}
}
int main()
{
std::thread tA(printA);
std::thread tB(printB);
tA.join();
tB.join();
return 0;
}
#include<iostream>
#include<condition_variable>
#include <mutex>
#include <thread>
std::mutex data_mutex;
std::condition_variable data_var;
void printA()
{
while(1)
{
std::this_thread::sleep_for(std::chrono::seconds(1));//类似于消费者
std::unique_lock<std::mutex> lck(data_mutex) ;//lck会自动解锁
std::cout<<"thread: "<< std::this_thread::get_id() << " printf: " << "A" <<std::endl;
data_var.notify_one();
data_var.wait(lck);
}
}
void printB()
{
while(1)
{
std::this_thread::sleep_for(std::chrono::seconds(2));//类似于生产者
std::unique_lock<std::mutex> lck(data_mutex) ;
std::cout<<"thread: "<< std::this_thread::get_id() << " printf: " << "B" <<std::endl;
data_var.notify_one();
data_var.wait(lck);
}
}
int main()
{
std::thread tA(printA);
std::thread tB(printB);
tA.join();
tB.join();
return 0;
}
//错误程序
#include<iostream>
#include<condition_variable>
#include <mutex>
#include <thread>
class print_a_b{
public:
print_a_b(){};
void printA()
{
while(1)
{
std::this_thread::sleep_for(std::chrono::seconds(1));//类似于消费者
std::unique_lock<std::mutex> lck(data_mutex) ;//lck会自动解锁
std::cout<<"thread: "<< std::this_thread::get_id() << " printf: " << "A" <<std::endl;
data_var.notify_one();
data_var.wait(lck);
}
}
void printB()
{
while(1)
{
std::this_thread::sleep_for(std::chrono::seconds(2));//类似于生产者
std::unique_lock<std::mutex> lck(data_mutex) ;
std::cout<<"thread: "<< std::this_thread::get_id() << " printf: " << "B" <<std::endl;
data_var.notify_one();
data_var.wait(lck);
}
}
private:
std::mutex data_mutex;
std::condition_variable data_var;
};
int main()
{
print_a_b A,B;
std::thread tA(A.printA());//传对象,而不是函数结果
std::thread tB(B.printB());
tA.join();
tB.join();
return 0;
}