本文共 2686 字,大约阅读时间需要 8 分钟。
头文件:#include 创建线程 void show(int x){ cout<<"hello,world"< < #include #include #include using namespace std;mutex mu;class show{public: void operator()(string msg){ for (int i=0; i<10; ++i) { cout< <<" "< < -10; --i) { cout< <<" "< < mutex mu;然后在cout使用之前加锁,使用后解锁mu.lock();cout< <<" "< < guard(mu);当guard析构时,无论是否掏出异常,mu将会被自动解锁。但是cout是一个全局变量,可能别的线程仍可以访问它,所以我们需要资源绑定绑定方法为自己实现一个ofstream 类对象 将执行结果输出在文件中。#include #include #include #include #include using namespace std;class logFile{ ofstream f; mutex m_mutex;public: logFile(){ f.open("/Users/shizheng/Desktop/log.txt"); } void print(string str,int i){ lock_guard guard(m_mutex); f< <<":"< < -10; --i) { log.print("Main thread", i); } t1.join(); return 0;}只要不将f泄露,就不会引起资源竞争。死锁,与解决死锁的办法先写一个出现死锁的小例子#include #include #include #include #include using namespace std;mutex mu;class logFile{ ofstream f; mutex m_mutex1,m_mutex2;public: logFile(){ f.open("/Users/shizheng/Desktop/log.txt"); } void print(string str,int i){ lock_guard guard1(m_mutex1); lock_guard guard2(m_mutex2); cout< <<":"< < guard2(m_mutex2); lock_guard guard1(m_mutex1); cout< <<":"< < -100; --i) { log.print2("Main thread", i); } t1.join(); return 0;}以上出现死锁的原因是因为print将mutex1锁住而print2需要mutex1,print2需要mutex2而此时mutex2被print锁住。解决办法void print(string str,int i){ lock(m_mutex1,m_mutex2); lock_guard guard1(m_mutex1,adopt_lock); lock_guard guard2(m_mutex2,adopt_lock); cout< <<":"< < guard2(m_mutex2,adopt_lock); lock_guard guard1(m_mutex1,adopt_lock); cout< <<":"< < guard1(m_mutex1,adopt_lock);//adopt_lock的作用是告诉guard1 只需要获取mutex的所有权,无需加锁 unique_lock locker(m_mutex1,defer_lock); //..... m_mutex1.lock(); cout< <<":"< < locker2 = move(locker);//unique_lock 可以局部加锁,比lock_guard有弹性,但是比lock_guard更多的消耗性能。defer_lock 表示,m_mutex1并没有被锁住once_flag m_flag;call_once(m_flag,[&](){f.open("log.txt");});//以上代码保证文件只被打开一次。多线程的条件变量以下代码为模拟生产者消费者模式,使用条件变量使消费者进程在等待生长过程中的多次循环,用条件变量在无产品时,自动休眠。#include #include #include #include #include using namespace std;queue q;mutex mu;condition_variable cond;void fun1(){ int count =10; while (count>0) { unique_lock locker(mu); q.push(count); mu.unlock(); cond.notify_one();//一但生产则唤醒休眠的消费者程序。notify_one为唤醒一个,notify_all为唤醒多个。 printf("生产者:%d\n",count); this_thread::sleep_for(chrono::seconds(1)); count--; }}void fun2(){ int data = 0,count=0; while (data!=1) { unique_lock locker(mu); cond.wait(locker,[](){return !q.empty();});//先解锁休眠进程,等待唤醒,唤醒后再加锁 //这里cond可能被自己激活,称为伪激活,第二个参数为lamda函数,队列不为空才会被激活 data = q.front(); q.pop(); mu.unlock(); printf("消费者:%d\n",data); count++; printf("消费者循环等待次数:%d\n",count); } }int main(){ thread t1(fun1); thread t2(fun2); t1.join(); t2.join(); return 0;}
转载地址:http://tehji.baihongyu.com/