future续谈、share_future、atomic、async深入谈



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

int mythread()  //线程入口函数
{
	cout << "mythread() start" << "thread id =" << this_thread::get_id() << endl;  //打印线程id
	chrono::milliseconds dura(3000);
	this_thread::sleep_for(dura);     //休息3s
	cout << "mythread() end" << "thread id =" << this_thread::get_id() << endl;  //打印线程id
	return 5;
}

//int g_mycount = 0;  //全局变量
atomic <int> g_mycount; //将全局变量修改为类型为int的atomic对象,则可以像操作int类型变量一样来操作这个对象
mutex my_mutex;
void count_thread()
{
	for (int i = 0; i < 10000000; i++)
	{

		/*
		//全局变量配合互斥量
		my_mutex.lock();  //加锁后,计算的值稳定,但消耗接近5秒
		g_mycount++;
		my_mutex.unlock();
		*/

		g_mycount++;  //修改为atomic对象,对应的操作是原子操作,不会被打断,且效率更高(接近2秒)

	}
}

int main()
{
	//一:future的其他函数
	 //int tempvar = 12;
	 //cout << "main  " << "thread id =" << this_thread::get_id() << endl;
	 //future <int> result = async(launch::deferred,mythread);   //自动创建一个线程并开始执行对应的线程入口函数,返回一个future对象。流程不会卡在这里
	 //cout << "continue.....!" << endl;
	 // cout << result.get() << endl;   //卡在这里等待mythread()执行完毕,拿到结果。只能调用一次,调用多次会报异常
	 
	 //wait_for:等待一定的时间
	 //枚举类型
	 //future_status status = result.wait_for(chrono::seconds(6));   //等待一秒
	 //if (status == future_status::timeout)   //等待一秒,希望返回
	 //{
		// //超时:表示线程还没执行完 
		// cout << "超时,线程还未执行完" << endl;
	 //}
	 //else if (status == future_status::ready)
	 //{
		// //表示线程成功返回
		// cout << "线程成功执行完毕,返回" << endl;
		// cout << result.get() << endl;
	 //}
	 //else if (status == future_status::deferred)
	 //{
		// //如果async的第一个参数被设置为launch::deferred,则本条件成立
		// cout << "线程被延迟执行" << endl;
		// cout << result.get() << endl;
	 //}
	 //cout << "主线程end" << endl;


	 //二:std::shared_future:也是个类模板,get()函数是复制数据,可以多次调用get。

	 //三:原子操作:atomic
	 //(3.1)原子操作概念引出范例
	 //互斥量:多线程编程中,保护共享数据,可以针对一行或多行代码(代码段)。  上锁->操作共享数据->开锁
	 //有两个线程,对一个变量进行操作,一个线程读,一个变量写
	 //可以把原子操作理解为: 不需要用到互斥量加锁(无锁)技术的多线程并发编程方式。在多线程中不会被打断的程序执行片段。
	 //原子操作效率比互斥量更好,但一般针对一个变量,而不是一个代码段
	 //原子操作一般指“不可分割的操作”。这种操作状态要么是完成的,要么是未开始的。不存在半完成的状态
	 //std::atomic来代表原子操作,是一个类模板,用来封装某个类型的值
	 thread t1(count_thread);
	 thread t2(count_thread);
	 t1.join();
	 t2.join();
	 cout << g_mycount << endl;  //如果不加锁,最后的结果不一定是2000万(不稳定)


	 //四:总结
	 //一般用于计数或者统计(累计发送出去多少个数据包,累计接收到了多少个数据包)
	return 0;
}


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

atomic <int> g_mycount = 0; //将全局变量修改为类型为int的atomic对象,则可以像操作int类型变量一样来操作这个对象
void count_thread()
{
	for (int i = 0; i < 10000000; i++)
	{
		g_mycount++;  
		g_mycount += 1;
		//g_mycount = g_mycount + 1;  //运行结果不稳定
	}
}

int mythread()
{
	cout << "my thread start, thread id =" << this_thread::get_id() << endl;
	return 1;
}

int main()
{
	//一:原子操作atomic续谈
	//一般原子操作,针对++,--,+=,-=,&=,|=,^= 等运算符是支持的,其他的可能不支持。
	/*thread t1(count_thread);
	thread t2(count_thread);
	t1.join();
	t2.join();
	cout << g_mycount << endl;*/


	//二:async深入谈
	//(2.1)async参数详谈。async用来创建一个异步任务;
	cout << "main thread start, thread id =" << this_thread::get_id() << endl;
	future<int> result = async(mythread);
	cout << result.get() << endl;
	//async()一般不叫创建线程(即使有时候它能够创建线程),一般叫它创建一个异步任务
	//thread(),如果系统资源紧张,那么创建线程就会失败,那么执行thread()时整个程序可能崩溃。

	//async与thread最明显的不同,就是async有时候并不创建新线程
	//a)如果用launch::deferred来调用async() :async(launch::deferred,mythread); 延迟调用,并不会创建线程,延迟到主线程调用wait和get时才会执行,否则不会执行。
	//b)async(launch::async,mythread):强制异步任务在新线程上执行(会创建新线程)
	//c)async(launch::async | launch::deferred,mythread):两种都有可能,由系统决定
	//d)async(mythread):不带参数时,效果同async(launch::async | launch::deferred,mythread),由系统自行决定调用方式(同步:不创建新线程还是异步:创建新线程)
	

	//(2.2)async()与thread()的区别
	//thread(),如果系统资源紧张,那么创建线程就会失败,那么执行thread()时整个程序可能崩溃
	//获取thread()入口函数返回值需要通过全局变量等手段来获取
	//async创建异步任务,可能创建线程也可能不创建线程,并且容易拿到线程入口函数的返回值
	//系统资源限制时:如果用thread()创建线程太多,则可能创建失败,系统报告异常,崩溃;
	//                如果用async,launch::async | launch::deferred或不带参数时,一般就不会报异常不会崩溃(在此情况下不创建新线程,会运行在调用get或wait的线程上)
	//一个程序里,线程数量不宜超过100 ~ 200 

	//(2.3)不确定性问题的解决
	//不带参数时,由系统自行决定调用方式,则存在不确定性
	//解决不确定性:
	future <int> result = async(mythread);
	//future_status status = result.wait_for(chrono::seconds(0)); //等0秒
	future_status status = result.wait_for(0s);   //同样也是等0秒
	if (status == future_status::deferred)
	{
		//线程被延迟执行了(系统资源紧张,采用launch::deferred策略了)
		cout << result.get() << endl;   //这个时候才去调用了mythread()

	}
	else
	{
		//任务没有被推迟,已经开始运行了,线程被创建了
		if (status == future_status::ready)
		{
			cout << result.get() << endl;
		}
		else if (status == future_status::timeout)
		{
			cout << "线程超时,没执行完" << endl;
		}
	}

	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值