future其他成员函数、shared_future、atomic

一、future其他成员函数

线程的三种状态。1.ready 2.time_out 3.deferred

#include <iostream>
#include <future>
#include <vector>

using namespace std;

int mythread()
{
	cout << "int mythread() start,thread id=" << std::this_thread::get_id() << endl;

	chrono::milliseconds dura(5000);
	this_thread::sleep_for(dura);

	cout << "int mythread() end,thread id=" << std::this_thread::get_id() << endl;

	return 5;
}

int main()
{
	cout << "int main(),beign,thread id=" << this_thread::get_id() << endl;
	
	//future<int> result = async(std::launch::deferred,mythread); //launch::deferred 不会创建子线程,是和主线程是一个线程
	future<int> result = async(mythread);
	cout << "continue...!" << endl;
	//cout << result.get() << endl;

	future_status status = result.wait_for(chrono::seconds(6));
	if (status == future_status::timeout)  //超时:表示线程还没执行完,希望1秒钟内就返回,但是没有返回,此时就会超时;
	{
		cout << "超时了,线程还没有执行完." << endl;
	}
	else if (status == future_status::ready)
	{
		cout << "表示线程成功返回了." << endl;
	}
	else if (status == future_status::deferred) // async 的第一个参数是std::launch::deferred 的话,这个条件就会成立。
	{
		cout << "async 的第一个参数是std::launch::deferred.,线程被延迟执行." << endl; 
		cout << result.get() << endl;
	}


	cout << "I Love China!" << endl;

	return 0;
}

二、std::shared_future

future 类模板的get() 函数,不能多次调用get()的原因是,比如下面代码就是错的。

future<int> tmp;

auto result = tmp.get();

auto result2 = tmp.get(); //错误,只能get()一次,不能get()两次

因为get()函数的设计是一个移动语义,第一次调用get()后,tmp中的内容已经全部都被移动到result中去了。

shared_future 里面同样有get()函数,这个里面的设计就不是移动语义,而是赋值语义。

三、原子操作

可以把原子操作理解成:不需要用到互斥量加锁(无锁)技术的多线程并发编程方式。也可以理解成在多线程中不会被打断的程序执行片断。原子操作在效率上,比互斥量更胜一筹。

互斥量:一般是加锁一个代码段(几行代码,或者一片代码)。

原子操作:针对的是一般都是一个变量,而不是一个代码段。一般都是指不可分割的操作,要么是完成的,要么是没有完成的,不可能是中间状态(半完成状态)。

C++11中,std::atomic 表示原子操作,std::atomic 是一个类模板,其实std::atomic 这个东西用来封装某个类型指的。

//互斥量版本

#include <iostream>
#include <future>
#include <vector>

using namespace std;



int g_mycount = 0;
std::mutex g_mutex;

void mythread()
{
	for (int i = 0; i < 1000000; i++)
	{
		g_mutex.lock();
		g_mycount++;
		g_mutex.unlock();
	}
	
	return;
}



int main()
{
	cout << "int main(),beign,thread id=" << this_thread::get_id() << endl;
	
	thread mytobj1(mythread);
	thread mytobj2(mythread);
	mytobj1.join();
	mytobj2.join();

	cout << "两个线程执行完毕,最终:g_mycount=" << g_mycount << endl;


	cout << "I Love China!" << endl;

	return 0;
}

原子操作版本:

demo1:

#include <iostream>
#include <future>
#include <vector>

using namespace std;



atomic<int> g_mycount = 0;  //封装了一个类型为int的对象(指),我们可以像操作一个int类型的变量,一样来操作g_mycount。
std::mutex g_mutex;

void mythread()
{
	for (int i = 0; i < 1000000; i++)
	{
		//g_mutex.lock();
		g_mycount++; //对应的操作是原子操作(不会被打断)
		//g_mutex.unlock();
	}
	
	return;
}



int main()
{
	cout << "int main(),beign,thread id=" << this_thread::get_id() << endl;
	
	thread mytobj1(mythread);
	thread mytobj2(mythread);
	mytobj1.join();
	mytobj2.join();

	cout << "两个线程执行完毕,最终:g_mycount=" << g_mycount << endl;


	cout << "I Love China!" << endl;

	return 0;
}

demo2:

#include <iostream>
#include <future>
#include <vector>
#include <atomic>
#include <thread>
 
using namespace std;
 
std::atomic<bool> g_ifend(false);  // Linux
//std::atomic<bool> g_ifend(false); windows 
 
void mythread()
{
	chrono::milliseconds dura(1000);
	while (g_ifend==false)
	{
		//系统没有要求线程退出,所以本线程可以干自己想干的事情
		cout << "thread id=" << this_thread::get_id()<< "运行中" << endl;
		std::this_thread::sleep_for(dura);
	}
	cout << "thread id=" << this_thread::get_id()<< "运行结束..." << endl;
	return;
}
 
int main()
{
	cout << "int main(),beign,thread id=" << this_thread::get_id() << endl;
	
	thread mytobj1(mythread);
	thread mytobj2(mythread);
 
	std::chrono::milliseconds dura(5000);
	std::this_thread::sleep_for(dura);
 
	g_ifend = true;
 
	mytobj1.join();
	mytobj2.join();
    
 
	cout << "I Love China!" << endl;
 
	return 0;
}

posted @ 2022-05-25 22:19  repinkply  阅读(34)  评论(0)    收藏  举报