【C++多線程系列】【九】future與async

若是咱們想要異步獲取線程處理結果,可使用future與async。async返回一個future對象,等待線程能夠在future對象上獲取異步線程的處理值。這裏的異步,實際上主線程會阻塞。ios

 

【一】future的狀態異步

future有三種狀態:async

std::future_status::deferred;  //表示異步線程還未啓動
std::future_status::ready;     //表示異步線程已經執行完畢,並已經將執行結果寫入到future中
std::future_status::timeout;   // 表示異步線程處理超時,並無將結果寫入future中

【二】async是否啓動線程函數

async是否啓動異步線程,有async第一個參數決定,async接口定義以下:this

async(std::launch::async | std::launch::deferred, f, args...)

第一個參數表示異步線程啓動的方式,有以下兩種方式:spa

std::launch::async; // 表示表用async函數後,當即啓動異步線程
std::launch::deferred; // 表示線程延遲啓動,當調用future.get或者future.wait時,纔會建立異步線程並啓動

而async的默認方式見接口所示:線程

std::launch::async | std::launch::deferred  // 表示是否啓動線程由系統負載決定,若是系統負載太重,則可能不啓動異步線程計算,則此時future的狀態不會爲ready, 通常狀況下,這種默認設置夠用了,可是若是須要必定以異步線程的方式執行,則顯示修改啓動方式爲async

【三】future的四個方法code

future<int> fu;
fu.get();

get聲明以下:對象

返回future中存取的int值,get在拿到數據以前,會一直阻塞接口

fu.wait();

wait聲明以下:

沒有返回值,一直等待,直到future狀態爲ready爲止

fu.wait_for();

wait_for聲明以下:

等待必定的時間,返回值爲future的狀態,若是等待超時,返回time_out

fu.wait_until();就是等待到某個時間點,與wait_for相似。

【四】async採用默認啓動參數

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;

int f(int i)
{
	cout << "start" << endl;
	cout << "this thread id = " << std::this_thread::get_id() << endl;
	std::this_thread::sleep_for(2s);
	cout << "end" << endl;
	return i;
}


int main(int argc, int * argv[])
{
	future<int> fu = std::async(f, 8);

	cout << fu.get() << endl;

	cout << "main thread id = " << std::this_thread::get_id() << endl;

	cout << "main" << endl;
	system("pause");
}

結果以下:

能夠看出,這裏線程id不同。

【五】先wait,後get

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;

int f(int i)
{
	cout << "start" << endl;
	cout << "this thread id = " << std::this_thread::get_id() << endl;
	std::this_thread::sleep_for(2s);
	cout << "end" << endl;
	return i;
}


int main(int argc, int * argv[])
{
	future<int> fu = std::async(f, 8);

	fu.wait();

	cout << fu.get() << endl;

	cout << "main thread id = " << std::this_thread::get_id() << endl;

	cout << "main" << endl;
	system("pause");
}

結果以下:

【六】等待超時

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;

int f(int i)
{
	cout << "start" << endl;
	cout << "this thread id = " << std::this_thread::get_id() << endl;
	std::this_thread::sleep_for(2s);
	cout << "end" << endl;
	return i;
}


int main(int argc, int * argv[])
{
	future<int> fu = std::async(f, 8);

	if (fu.wait_for(1s) == std::future_status::timeout) {
		cout << "time out" << endl;
	}
	else {
		cout << fu.get() << endl;
	}


	cout << "main thread id = " << std::this_thread::get_id() << endl;

	cout << "main" << endl;
	system("pause");
}

結果以下:

若是超時了還get,則會繼續等待,直到future狀態爲ready,而後取出數據

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;

int f(int i)
{
	cout << "start" << endl;
	cout << "this thread id = " << std::this_thread::get_id() << endl;
	std::this_thread::sleep_for(2s);
	cout << "end" << endl;
	return i;
}


int main(int argc, int * argv[])
{
	future<int> fu = std::async(f, 8);

	if (fu.wait_for(1s) == std::future_status::timeout) {
		cout << "time out" << endl;
	}
    // 超時繼續get
    cout << fu.get() << endl;



	cout << "main thread id = " << std::this_thread::get_id() << endl;

	cout << "main" << endl;
	system("pause");
}

結果以下:

 

【七】設置aysnc啓動方式

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;

int f(int i)
{
	cout << "start" << endl;
	cout << "this thread id = " << std::this_thread::get_id() << endl;
	std::this_thread::sleep_for(2s);
	cout << "end" << endl;
	return i;
}


int main(int argc, int * argv[])
{
    // 設置啓動方式爲async
	future<int> fu = std::async(std::launch::async,f, 8);

	if (fu.wait_for(1s) == std::future_status::timeout) {
		cout << "time out" << endl;
	}

    cout << fu.get() << endl;



	cout << "main thread id = " << std::this_thread::get_id() << endl;

	cout << "main" << endl;
	system("pause");
}

結果以下:

相關文章
相關標籤/搜索