创建多个线程案例
void myprint(int inum)
{
cout << "myprint start" << inum<< endl;
return;
}
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();
}
return 0;
}
多个线程读数据
vector<int> g_v = {1,2,3};//共享数据,只读
void myprint(int inum)
{
cout << "id为: " << this_thread::get_id()<< "打印的g_v值" << g_v[0] << g_v[1] << g_v[2] << endl;
return;
}
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();
}
return 0;
}
多线程有读有写
访问共享数据的时候,如果写一半,然后读线程访问共享数据是不是就会异常,所以在访问共享数据的时候,会共享数据的访问进行锁 保护起来
一个c++解决多线程保护共享数据问题的一个概念 “互斥量”
#include <iostream>
#include <string>
#include <thread>
#include <vector>
#include <list>
using namespace std;
class A {
public:
//把收到的消息(玩家命令) 入到一个队列的线程
void inMsgRecvQueue()
{
for (int i = 0; i < 10000; i++) {
cout << "inMsgRecvQueue执行,插入一个元素" << i << endl;
msgRecvQueue.push_back(i);//假设这个数字就是收到的命令
}
}
void outMsgRecvQueue()
{
for (int i = 0; i < 10000; i++)
{
if (!msgRecvQueue.empty()) {
int command = msgRecvQueue.front();//读头部元素
msgRecvQueue.pop_front();//移除头部元素
//处理数据
cout << "接收到命令,处理命令" << command << endl;
}
else
{
cout << "outMsgRecvQueue执行,但目前消息队列为空" << i << endl;
}
}
}
private:
list<int> msgRecvQueue; //容器,专门用于代表玩家给咱们发送过来的命令
};
int main()
{
//数据共享问题分析
//只读的数据:安全稳定,不需要特别说明处理手段,直接读就可以
//有读有写:2个写线程、8个读线程,如果代码没有特别的处理,那程序肯定崩溃
//最简单的不崩溃处理,读的时候不能写,写的时候不能读,2 个线程不能同时写,8个线程不能同时读
//共享数据的保护案例代码
//网络游戏服务器:两个自己创建的线程,一个线程收集玩家命令,并把命令数据写到一个队列中
//另一个线程从队列中取出玩家发送过来的命令,解析,然后执行
//list频繁的按顺序插入数据和删除数据效率高
//vector容器随机的插入和删除数据效率高
//所以队列使用list
A mya;
thread Rthread(&A::outMsgRecvQueue,&mya);//第二个参数,带引用,就不会被拷贝一分了,这个就不能用detach了
thread Wthread(&A::inMsgRecvQueue, &mya);
Rthread.join();
Wthread.join();
return 0;
}