一、创建和等待多个线程
#include <thread>
#include <iostream>
#include <vector>
using namespace std;
void myprint(int inum)
{
cout << "myprint线程开始执行了,线程编号 = " << inum << endl;
cout << "myprint线程执行结束了,线程编号 = " << inum << endl;
}
int main()
{
vector<thread> mythreads;
for (int i = 0; i < 10; i++)
{
mythreads.push_back(thread(myprint, i));
}
for (auto iter = mythreads.begin(); iter != mythreads.end(); ++iter)
{
iter->join();
}
cout << "I love chain !" << endl;
return 0;
}
二、数据共享问题分析
1.只读的数据
- 只读数据是安全稳定的,只需要读就可以,不需要特别的处理
#include <thread>
#include <iostream>
#include <vector>
using namespace std;
vector<int> e_v = { 1,2,3 };
void myprint(int inum)
{
cout << "id 为" << std::this_thread::get_id() << "的线程 打印 g_v 的值" << e_v[0] << e_v[1] << e_v[2] << endl;
}
int main()
{
vector<thread> mythreads;
for (int i = 0; i < 10; i++)
{
mythreads.push_back(thread(myprint, i));
}
for (auto iter = mythreads.begin(); iter != mythreads.end(); ++iter)
{
iter->join();
}
cout << "I love chain !" << endl;
return 0;
}
2.只写的数据
- 创建10个线程,2个线程写数据,8个线程读数据,如果没有特别的处理,程序肯定崩溃
- 最简单的不崩溃处理,读的时候不能写,写的时候不能读
- 2个线程不能同时写,8个线程也不能同时读
- 假如写分为10小步,由于任务切换,导致各种诡异的事情发生
- 一个写动作需要一次性被完成,不能被打断
3.其他案例
- 案例:北京—> 深圳火车,10个售票窗口,1和2号窗口同时要定 99 号坐;
分两步:查看该座位是否被预定,没有预定则预定,预定了则返回已预定
三、共享数据的保护案例代码
- 这段代码还有问题:共享数据读写矛盾
- 解决方法:因为一个概念 “互斥量”
#include <thread>
#include <iostream>
#include <list>
using namespace std;
class A
{
public:
void inMsgRecvQueue()
{
for (int i = 0; i < 100000; ++i)
{
cout << "inMsgRecvQueue()执行,插入一个元素" << i << endl;
msgRecvQueue.push_back(i);
}
}
void outMsgRecvQueue()
{
for (int i = 0; i < 100000; ++i)
{
if (!msgRecvQueue.empty())
{
int command = msgRecvQueue.front();
msgRecvQueue.pop_front();
}
else
{
cout << "outMsgRecvQueue()执行,但目前消息队列为空" << i << endl;
}
}
}
private:
list<int> msgRecvQueue;
};
int main()
{
A myobja;
thread myOutMsgobj(&A::outMsgRecvQueue, &myobja);
thread myInMsgobj(&A::inMsgRecvQueue, &myobja);
myOutMsgobj.join();
myInMsgobj.join();
return 0;
}
|