多线程condition_variable
2019年4月11日
本博客主要介绍利用条件变量进行多线程编程。
当
std::condition_variable
对象的某个
wait()
被调用时,它使用
std::unique_lock
来锁住当前线程,当前线程会一直阻塞,直到另外一个线程唤醒这个线程。
#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <chrono>
using namespace std;
condition_variable cv;//全局条件变量
mutex mtx;//全局互斥锁
bool ready = false;
void file(){//这个线程用来将字符串写入文件,并唤醒后面等待读取文件的线程。
unique_lock<mutex> lock(mtx); //获取全局互斥锁
FILE *fp = fopen("test.txt","w");
fprintf(fp,"班级1703018,学号17030188005");
fclose(fp);
ready = true;//将标志设置为true并唤醒等待线程
cv.notify_all();
}
void print(){//输出文件的内容
unique_lock<mutex> lock(mtx);
cv.wait(lock,[]{return ready;});//将线程阻塞,这里注意后面的标志要求可重复执行,也就是说,要用λ表达式,或者直接是一个函数,不能直接填写ready.
FILE *FP = fopen("test.txt","r");
char content[100]={0};
fgets(content,100,FP);
cout<<content<<endl;
}
int main(){
int sum = 0;
for(int i = 1;i<=100;i++){
sum += i;
cout<<sum<<endl;
this_thread::sleep_for(chrono::milliseconds(50));
}
thread t(file);//创建文件写入的线程
thread k(print);//创建文件读取的线程
t.join();//将子线程加入,这样的目的是防止主线程执行完成后,子线程还没有执行完成,然后报错。
k.join();
}
同样,线程阻塞还可以用
condition_variable::wait_for(),和condition_variable::wait_until()
完成,这两个函数的阻塞结束的标志是时间,比如
cv.wait_for(lck,std::chrono::seconds(1))
,对于
wait()
来说还可以直接
cv.wait(lck)
,这样,就不需要标志和唤醒同时满足,直接阻塞然后等待其他线程唤醒即可。其他情况可以参考
www.2cto.com/kf/201506/411327.html
。
Previous
UNIX fork()以及管道pipe()
Newer