1. 程式人生 > >future其他成員函式,shared_future、atomic

future其他成員函式,shared_future、atomic

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

int main()
{
	cout << "main id = " << std::this_thread::get_id() << endl;
	//async 非同步,等全部執行緒執行完主函式才返回
	//std::future<int> result = std::async(mythread);
	std::future<int> result = std::async(std::launch::deferred,mythread);
	/*cout << result.get() << endl;*/
	//列舉型別
	std::future_status status = result.wait_for(std::chrono::seconds(3));
	if (status == std::future_status::timeout)
	{
		//超時表示執行緒還沒執行完;
		cout << " time out " << endl;
	}
	else if (status == std::future_status::ready)
	{
		//表示執行緒成功返回
		cout << " ready " << endl;
		cout << result.get() << endl;
	}
	else if(status == std::future_status::deferred)
	{
		//如果async的第一個引數設定為 std::launch::def
		cout << "執行緒延遲執行" << endl;
		cout << result.get() << endl;
	}

	cout << "continue.... " << endl;
	return 0;
}

std::shread_future:也是類模板,get()函式只是複製資料

int mythread()
{
	cout << "mythread() start" << " thread id = " << std::this_thread::get_id() << endl;
	std::this_thread::sleep_for(2s);
	return 5;
}

void mythread2(std::shared_future<int> &temp)
{
	cout<<"mythread2() start" << " thread id = " << std::this_thread::get_id() << endl;
	auto result = temp.get();
	cout << "mythread2 result = " << result << endl;
	return;
}
int main()
{
	cout << "main id = " << std::this_thread::get_id() << endl;

	std::packaged_task<int(void)> mypt(mythread);

	std::thread t1(std::ref(mypt));
	t1.join();

	//std::future<int> result = mypt.get_future();
	////std::shared_future<int> result_s(std::move(result));
	//std::shared_future<int> result_s(result.share());
	//shared_future的get()函式只是複製資料
	shared_future<int>result_s(mypt.get_future());

	std::thread t2(mythread2, std::ref(result_s));
	t2.join();

	cout << "continue.... " << endl;
	return 0;
}

當兩個執行緒同時修改一個全域性變數時,可能會出錯

int g_mycount = 0;
void mythread()
{
	cout << "mythread() start" << " thread id = " << std::this_thread::get_id() << endl;
	for (int i = 0; i < 10000000; i++)
	{
		g_mycount++;
	}
	return;
}
int main()
{
	cout << "main id = " << std::this_thread::get_id() << endl;

	thread mytobj1(mythread);
	thread mytobj2(mythread);
	mytobj1.join();
	mytobj2.join();

	cout << "g_mucount = " << g_mycount << endl;
	cout << "continue.... " << endl;
	return 0;
}

在這裡插入圖片描述

atomic:針對++,–,+=,&=,|=,&=,|=,^=是支援的。其它的可能不支援。

std::atomic<int> g_mycount = 0;//封裝一個型別為int的物件
std::atomic<bool> g_ifend = false;//執行緒退出標記。防止讀寫亂套
void mythread()
{
	while(g_ifend == false)
	{
		cout << "mythread() start" << " thread id = " << std::this_thread::get_id() << endl;
		std::this_thread::sleep_for(2s);
	}
	cout << "mythread() end" << " thread id = " << std::this_thread::get_id() << endl;
	return;
}
int main()
{
	//原子操作:不需要用到互斥量加鎖技術的多執行緒併發程式設計方式
	//在多執行緒中,不會被打斷程式的執行片段,比互斥量效率上更勝一籌。
	//互斥量的加鎖一般是針對一個程式碼段(幾行程式碼或者更多),而原子操作針對的是一個變數。
	//std::atomic來代表原子操作,是個類模板。是用來封裝某個型別的值。
	cout << "main id = " << std::this_thread::get_id() << endl;

	thread mytobj1(mythread);
	thread mytobj2(mythread);
	std::this_thread::sleep_for(5s);
	g_ifend = true;

	mytobj1.join();
	mytobj2.join();
	


	
	cout << "continue.... " << endl;
	return 0;
}

std::async引數詳述:用來建立一個非同步任務
std::launch::deferred 延遲呼叫,並且不建立新執行緒,並在.get()或.wait()呼叫時才執行執行緒函式
std::launch::async 強制建立一個執行緒
std::thread() 如果系統資源緊張,那麼可能建立執行緒就會失敗,那麼執行thread()時整個程式可能崩潰。
std::async() 一般叫 建立一個非同步任務
std::async 和 thread 不同: async有時候並不建立執行緒。
如果兩個引數一起呼叫(或不帶引數),那就由系統選擇。

系統如何決定是 建立新執行緒還是同步方式執行。
std::thread建立執行緒的方式,如果執行緒返回值,你想拿到這個值也不容易。
由於系統資源限制
1)如果用thread建立的執行緒太多,則可能建立失敗,系統報告異常,崩潰
2)如果用async,一般就不會報異常不會崩潰,因為如果系統資源緊張導致無法建立新執行緒的時候,
async這種不加額外引數的呼叫就不會建立新執行緒,而是後續誰呼叫了 .get()的執行緒中繼續執行。


async不確定性問題解決
不加引數的async呼叫 std::future<int>result = std::async(mythread);
使用wait_for 解決