C++多线程编程
2018-03-23 10:04
197 查看
C++多线程demo
之前对多线程编程一直不了解,在编写工具时有一个工具使用了多线程编程,但在工具运行时,关闭工具会出现程序崩溃情况,所以了解了多线程编程的基础,写了一个生产者与消费者的demo,程序采用vs2015,C++11,VS2010不支持多线程编程,demo如下:生产者与消费者
产品个数上限为10个,下限为0个,当产品为0时,产品不能被消费,只能生产,当产品个数超过10个,不能继续生产,只能被消费。#include <thread> #include <mutex> #include <condition_variable> #include <queue> #include <vector> #include<iostream> class CThreadDemo { private: std::mutex m_mtx; // 全局互斥锁. std::condition_variable m_cv; // 全局条件变量,阻塞一个或多个线程,直到得到通知 int m_nGen;//产品个数,共享变量、临界区 private: void ProductThread() { while (true) { std::unique_lock <std::mutex> lck(m_mtx);//锁定共享变量 while (m_nGen >=10) { std::cout << "Product is enough!" << std::endl; m_cv.wait(lck);//=0时,线程等待,通知消费者线程消费 } m_nGen = ++m_nGen ; printf("product %d\n", m_nGen); lck.unlock();//解锁共享变量,能被其他线程使用 m_cv.notify_all(); /* 等待1S */ std::chrono::milliseconds dura(1000); std::this_thread::sleep_for(dura);//等待 } } void ConsumeThread() { while (true) { std::unique_lock <std::mutex> lck(m_mtx);//上锁 while (m_nGen <= 0) { std::cout << "Product is not enough!" << std::endl; m_cv.wait(lck);//<=0时,线程等待,直到大于0 } m_nGen = --m_nGen; printf("consume %d\n", m_nGen); lck.unlock();//解锁 m_cv.notify_all(); /* 等待2S */ std::chrono::milliseconds dura(1000); std::this_thread::sleep_for(dura); } } public: CThreadDemo() { m_nGen = 0; } //线程个数不要超过计算机核数的两倍 void Start() { std::vector<std::thread> threads; threads.clear(); for (int i = 0; i < 10; i++) {/* 生产者线程 */ threads.push_back(std::thread(&CThreadDemo::ProductThread, this));//参数传递 } for (int i = 10; i < 18; i++) {/* 消费者线程 */ threads.push_back(std::thread(&CThreadDemo::ConsumeThread, this)); } for (auto& t : threads) {/* 等待所有线程的退出 */ t.join(); } } }; int main() { CThreadDemo test; test.Start(); return 0; }
注意点
多线程最核心的问题在于资源竞争,例如控制台,控制台只有一个,可以有多个线程,但每个时间只能有一个线程能拥有控制台。关于detch( )和 join()表示线程的一种状态,必须在线程生命周期结束前确定是那种方式:
在任何一个时间点上,线程是可结合的(joinable),或者是分离的(detached)。
一个可结合的线程 (join) 能够被其他线程收回其资源和杀死;在被其他线程回收之前,它的存储器资源(如栈)是不释放的,join方式,等待启动的线程完成,才能继续向下执行。
一个分离的线程 (detach) 是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放,启动的线程在后台运行,当前的代码继续执行,不等待新线程的结束,是真正的后台运行。
参数传递:
如果需要将参数按引用传递,那要向下例所示那样,必须将参数用std::ref 或者std::ref进行封装。
std::thread p1(function,std::ref(a),"asdasd");
线程赋值:
std::thread p2=std::move(p1);
互斥量是用来保护多线程同时访问的共享数据,与lock()和unlock()搭配使用。分为std::mutex,最基本的数据量,std::time_mutex,带超时的独占互斥量,可以理解为定义获得锁的时间,std::recursive_mutex递归互斥量,防止死锁,std::recursive_time_mutex,是有两种情况。
std::condition_variable,配合std::unique_lock进行wait操作:
1.拥有条件变量的线程获取互斥锁
2.循环检查某个条件,如果条件不满足,则阻塞直到条件满足如果条件满足,则向下执行。
3.某个线程满足条件执行完之后调用notify_one或者notify_all
相关文章推荐
- C++多线程编程(★入门经典实例★)
- 使用 C++ 和 MFC 进行多线程编程
- C++多线程编程简单实例
- win32 C++多线程编程简单实例
- C++多线程编程学习一 [关于数据竞争问题]
- C++工程师面试宝典系列之多线程编程
- C++ 多线程编程总结
- c++多线程编程
- C++多线程编程――线程的挂起、唤醒与终止
- C++多线程编程
- linux C++ 多线程编程
- 新手学C++多线程编程(1)组件
- 新手学C++多线程编程(10)类行为和线程处理
- Linux下C++的多线程编程
- windiws C++ 多线程编程
- 【C/C++开发】多线程编程中的join函数
- 【C++】:C++多线程编程
- 新手学C++多线程编程(11)测试多线程应用程序
- Linux C++的多线程编程
- C++多线程编程简单实例