1. 程式人生 > >c++11特性裡的多執行緒thread的用法

c++11特性裡的多執行緒thread的用法

建立和啟動一條C++執行緒就像在C++原始碼中新增執行緒標頭檔案那麼簡便。我們來看看如何建立一個簡單的帶執行緒的HelloWorld:

#include <iostream>
#include <thread>
using namespace std;
 
//This function will be called from a thread
//該函式將在一條執行緒中得到呼叫
 void call_from_thread()
 {
 	cout << "hello world!" << endl;
 }
 
 int main()
 {
	 //Launch a thread
	 //啟動一條執行緒
 	thread t1(call_from_thread);
	//Join the thread with the main thread
	//和主執行緒協同
 	t1.join();
 	return 0;
 }

輸出:Hello world!

在真實世界的應用程式中,函式“call_from_thread”相對主函式而言,獨立進行一些運算工作。在上述程式碼中,主函式建立一條執行緒,並在t1.join()處等待t1執行緒執行結束。如果你在編碼中忘記考慮等待一條執行緒結束執行,主執行緒有可能搶先結束它自己的執行狀態,整個程式在退出的時候,將殺死先前建立的執行緒,不管函式“call_from_thread”有沒有執行完。

我們通常希望一次啟動多個執行緒,來並行工作。為此,我們可以建立執行緒組,而不是上面舉例中那樣建立一條執行緒。下面的例子中,主函式建立十條為一組的執行緒,並且等待這些執行緒完成他們的任務:

#include <iostream>
#include <thread>
using namespace std;

static const int num_threads = 10;
void call_from_thread(int tid) 
{
	cout << "Launched by thread" <<tid<< endl;
}
int main()
{
	thread t[num_threads];
	//Launch a group of threads 啟動一組執行緒
	for (int i = 0; i < num_threads;++i)
	{
		t[i] = thread(call_from_thread,i);
	}
	cout << "Launched from the main";
	//Join the threads with the main thread
	for (int i = 0; i < num_threads;++i)
	{
		t[i].join();
	}
	return 0;
}
說明:記住,主函式也是一條執行緒,通常叫做主執行緒,所以上面的程式碼實際上有11條執行緒在執行。在啟動這些執行緒組之後,執行緒組和主函式進行協同(join)之前,允許我們在主執行緒中做些其他的事情。

線上程中使用帶有形參的函式,是怎麼一回事呢?C++11允許我們線上程的呼叫中,附帶上所需的任意引數。

輸出:

能看到上面的結果中,程式一旦建立一條執行緒,其執行存在先後秩序不確定的現象。程式設計師的任務就是要確保這組執行緒在訪問公共資料時不要出現阻塞。事實上假定在你自己的機器上執行上面的程式碼,將會獲得全然不同的結果,甚至是會輸出些混亂的字元。原因在於,程式內的11條執行緒都在競爭性地使用stdout這個公共資源。
要避免上面的問題,可以在程式碼中使用攔截器(barriers),如std:mutex,以同步(synchronize)的方式來使得一群執行緒訪問公共資源,或者,如果可行的話,為執行緒們預留下私用的資料結構,避免使用公共資源。