C++并发与多线程(三)

1.创建个等待多个线程

// 并发与多线程2_4.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include <vector>
#include <thread>
using namespace std;

void Myprint(int inum)
{
	cout << "myprint线程开始执行了,线程编号" << inum << endl;
	cout << "myprint线程结束执行了,线程编号" << inum << endl;

}



int main()
{
    //一 创建线程和等待多个线程
	vector<thread>mythreads;
	//创建10个线程,线程入口函数统一使用 myprint
	//1)多线程执行顺序是乱的
	//2)这种join写法更容易写出稳定程序
	//3)把thread对象放入到容器里,对管理大量线程有帮助
	for (int i = 0; i < 10; i++)
	{
		//创建10个线程,已经开始执行
		mythreads.push_back(thread(Myprint, i));
	
	}
	for (auto iter = mythreads.begin(); iter != mythreads.end(); ++iter)
	{
		iter->join();
	}
	cout << "I LOVE CHINA" << endl;

}

2.数据共享问题分析

2.1只读数据共享

只读数据共享安全稳定

// 并发与多线程2_4.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include <vector>
#include <thread>
using namespace std;


vector<int>g_v = { 1,2,3 };

void Myprint(int inum)
{
	cout << "myprint线程开始执行了,线程编号" << inum << endl;
	cout << "myprint线程结束执行了,线程编号" << inum << endl;
	cout << "id 为" << std::this_thread::get_id() << "打印g_v值" << g_v[0] << g_v[1] << g_v[2] << endl;

}



int main()
{
    //一 创建线程和等待多个线程
	vector<thread>mythreads;
	//创建10个线程,线程入口函数统一使用 myprint
	//1)多线程执行顺序是乱的
	//2)这种join写法更容易写出稳定程序
	//3)把thread对象放入到容器里,对管理大量线程有帮助
	for (int i = 0; i < 10; i++)
	{
		//创建10个线程,已经开始执行
		mythreads.push_back(thread(Myprint, i));
	
	}
	for (auto iter = mythreads.begin(); iter != mythreads.end(); ++iter)
	{
		iter->join();
	}
	cout << "I LOVE CHINA" << endl;

	//二 数据共享
	//2.1只读数据

}


2.2 有读有写的数据

最简单的不崩溃处理 读和写不能同时进行

3.共享数据的保护案例代码

如果写和读同时进行,则会报错
这里就需要一个保护共享数据的互斥量的概念

// 并发与多线程2_4.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include <vector>
#include <thread>
#include <list>
using namespace std;


//vector<int>g_v = { 1,2,3 };
//
//void Myprint(int inum)
//{
//	cout << "myprint线程开始执行了,线程编号" << inum << endl;
//	cout << "myprint线程结束执行了,线程编号" << inum << endl;
//	cout << "id 为" << std::this_thread::get_id() << "打印g_v值" << g_v[0] << g_v[1] << g_v[2] << endl;
//
//}



class A
{
public:
	//把玩家命令放入到一个队列的进程
	void inMsgRecvQueue()
	{
		for (int i = 0; i < 100; i++)
		{
			cout << "inMsgRecvQueue执行,插入一个元素" << i << endl;
			msgRecvQueue.push_back(i);     //假设数字i为命令 放入队列		
		}
	}

	//读取命令的线程
	void outMsgRecvQueue()
	{
	
		for (int i = 0; i < 100; i++)
		{
			if (!msgRecvQueue.empty())
			{
				int command = msgRecvQueue.front();      //返回第一个元素但不检查元素是否存在
				msgRecvQueue.pop_front();            //移除第一个元素但不返回
				//处理数据。。。。。
			
			}
			else
			{
				cout << "outMsgRecvQueue()执行,但目前消息队列为空" <<i<< endl;
			}
		}
		cout << "end" << endl;
	
	}
private:

	std::list<int>msgRecvQueue;

};

int main()
{
 //   //一 创建线程和等待多个线程
	//vector<thread>mythreads;
	创建10个线程,线程入口函数统一使用 myprint
	1)多线程执行顺序是乱的
	2)这种join写法更容易写出稳定程序
	3)把thread对象放入到容器里,对管理大量线程有帮助
	//for (int i = 0; i < 10; i++)
	//{
	//	//创建10个线程,已经开始执行
	//	mythreads.push_back(thread(Myprint, i));
	//
	//}
	//for (auto iter = mythreads.begin(); iter != mythreads.end(); ++iter)
	//{
	//	iter->join();
	//}
	//cout << "I LOVE CHINA" << endl;

	//二 数据共享
	//2.1只读数据
	//2.2 有读有写
	//最简单的不崩溃处理 读和写不能同时进行
	//2.3其他案例
	//数据共享:    

	//三 共享数据的保护案例代码
	//网络游戏服务器,有两个自己创建的线程,一个线程手机玩家命令(数字表示),并把名利数据写入到一个队列中。
	//另一个线程从队列中取出玩家发送来的命令,解析,然后执行玩家的动作。
	//使用list,频繁的按顺序插入和删除时效率较高


	//用成员函数作为线程函数的方法写线程

	A myobja;
	thread myOutnMsg(&A::outMsgRecvQueue, &myobja);
	thread myInMsgObj(&A::inMsgRecvQueue, &myobja);
	myOutnMsg.join();
	myInMsgObj.join();

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Michael.Scofield

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值