多线程程序

竞态条件:多线程程序执行的结果是一致的,不会随着CPU对线程不同的调用顺序而产生不同的运行结果.

解决?:互斥锁 mutex

经典的卖票问题,三个线程卖100张票

代码1

#include <iostream>
#include <thread>
#include <list>
#include <mutex>
int ticketCount = 100; std::mutex mtx;//互斥锁 void sellTicket(int window) { while (ticketCount > 0) { mtx.lock();
std::cout << "窗口" << window << "销售" << ticketCount << std::endl;
ticketCount--;
mtx.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(50)); } }//end int main() { std::list<std::thread> tlist; for (int i = 0; i < 3; i++) {
tlist.push_back(std::thread(sellTicket,i));
} for (std::thread & t : tlist) {
t.join();
} system("pause");
return 0;
}

上面代码的问题...

while (ticketCount > 0) {

    mtx.lock();
std::cout << "窗口" << window << "销售" << ticketCount << std::endl;
ticketCount--;
mtx.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(50)); }
如果ticketCount =1 ,当前有一个线程A while (ticketCount > 0)为true,线程A还没执行ticketCount--完成时,cpu交给了线程B
线程B while (ticketCount > 0)也为true,进入 循环体内,造成了买0号票,改进如下

代码2

#include <iostream>
#include <thread>
#include <list>
#include <mutex>
int ticketCount = 100; std::mutex mtx;//互斥锁 void sellTicket(int window) { while (ticketCount > 0) { mtx.lock();
if(ticketCount >0){
std::cout << "窗口" << window << "销售" << ticketCount << std::endl;
ticketCount--;
}
mtx.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(50));
} }//end int main() { std::list<std::thread> tlist; for (int i = 0; i < 3; i++) {
tlist.push_back(std::thread(sellTicket,i));
} for (std::thread & t : tlist) {
t.join();
} system("pause");
return 0;
}

代码2还有些问题!! 如下

mtx.lock();
代码
代码
代码
代码
.....
mtx.unlock(); 如果在代码lock()和unlock()之间 非常返回,导致mtx没有正常unlock(),那么出现死锁问题 =》智能指针 lock_gurad unique_lock

看lock_gurad

#include <iostream>
#include <thread>
#include <list>
#include <mutex>
int ticketCount = 100; std::mutex mtx;//互斥锁 void sellTicket(int window) { while (ticketCount > 0) { {
std::lock_guard<std::mutex> lock(mtx);
std::cout << "窗口" << window << "销售" << ticketCount << std::endl;
ticketCount--;
std::this_thread::sleep_for(std::chrono::milliseconds(50)); } } }//end int main() { std::list<std::thread> tlist; for (int i = 0; i < 3; i++) {
tlist.push_back(std::thread(sellTicket,i));
} for (std::thread & t : tlist) {
t.join();
} system("pause");
return 0;
}

上面的图片中我们知道lock_gurad 的拷贝构造函数被关闭了,所以当我们遇到函数调用需要拷贝构造lock_guard的时候,就有障碍了,这个时候可以用unique_lock

unique_lock 转移指针,支持带右值得拷贝赋值,支持参数传递拷贝构造的,他的左值的拷贝构造也是被关闭了 看下图

最新文章

  1. Virtual Box 下Ubuntu桥接网络设置
  2. 8、需求分析师要阅读的书籍 - IT软件人员书籍系列文章
  3. Hive UDF开发实例学习
  4. [转]SOLID开发原则-面向对象
  5. Learning Lua Programming (2) Lua编程基础
  6. Codeforces Gym 100342J Problem J. Triatrip bitset 求三元环的数量
  7. Ng机器学习笔记-1-一元线性回归
  8. 安卓 eclipse项目创建
  9. OSG+VS2010+win7环境搭建
  10. java课程设计-算术运算测试
  11. 利用位运算进行a+b的计算(Java&&Python)
  12. LOJ2527 HAOI2018 染色 容斥、生成函数、多项式求逆
  13. Python RabbitMQ消息分发轮询
  14. PyCharm:ModuleNotFoundError: No module named &#39;selenium&#39;
  15. git工具
  16. VS2012高亮显示当前行背景色的问题
  17. web前端面试小结(1)
  18. 快速上手Vue
  19. Jmeter的log输出控制
  20. js javascript 实现多线程

热门文章

  1. 使用KubeOperator安装k8s集群后,节点主机yaml文件路径
  2. 使用 fail2ban 和 FirewallD 黑名单保护你的系统
  3. AlertManager 之微信告警模板,UTC时间错8个小时的解决办法
  4. POJ3237 Tree (树链剖分)
  5. mac通过docker一键部署MySQL8
  6. day08-MySQL事务
  7. java中获取当前执行线程的名称
  8. SpringCloud微服务实战——搭建企业级开发框架(四十六):【移动开发】整合uni-app搭建移动端快速开发框架-环境搭建
  9. 十七、Job与Cronjob
  10. 四、Pod 介绍