博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
待修改:C++多线程编程学习笔记
阅读量:4070 次
发布时间:2019-05-25

本文共 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/

你可能感兴趣的文章
司法如何运用电子智能化加快现代化建设
查看>>
iSecret&nbsp;1.1&nbsp;正在审核中
查看>>
IOS开发的开源库
查看>>
IOS开发的开源库
查看>>
Jenkins - sonarqube 代码审查
查看>>
Jenkins + Docker + SpringCloud 微服务持续集成(一)
查看>>
Jenkins + Docker + SpringCloud 微服务持续集成 - 单机部署(二)
查看>>
Jenkins + Docker + SpringCloud 微服务持续集成 - 高可用集群部署(三)
查看>>
Golang struct 指针引用用法(声明入门篇)
查看>>
Linux 粘滞位 suid sgid
查看>>
C#控件集DotNetBar安装及破解
查看>>
Winform皮肤控件IrisSkin4.dll使用
查看>>
Winform多线程
查看>>
C# 托管与非托管
查看>>
Node.js中的事件驱动编程详解
查看>>
mongodb 命令
查看>>
MongoDB基本使用
查看>>
mongodb管理与安全认证
查看>>
nodejs内存控制
查看>>
nodejs Stream使用中的陷阱
查看>>