C++11 併發與多執行緒篇(未完成)
從C++11新標準開始,C++語言本身增加了對多執行緒的支援,意味著使用C++可實現多執行緒程式的可移植,跨平臺。
在標準的C++程式中,主執行緒從main()開始執行,我們自己在C++中建立的執行緒,也需要從一個函式開始執行(這個函式叫做初始函式),一旦這個函式執行完畢,我們建立的執行緒也就執行結束了。
一個書寫良好的程式,必須等所有的子執行緒執行完畢之後,主執行緒才能結束。
一、C++11建立執行緒基本方法
1.1 使用函式建立執行緒
1 新增標頭檔案
新增標頭檔案以使用多執行緒:#include <thread>
1 建立初始函式
定義一個函式,這個函式將會作為我們建立的執行緒的初始函式:
void thread_function()
{
cout << "start executing my thread..." << endl;
}
3 在程式中新增執行緒,以及基本的執行緒函式
新建一個執行緒使用:
thread 執行緒名稱(初始函式)
join()函式
用法:執行緒名稱.join()
說明:使用該函式後,主執行緒阻塞到這裡,當子執行緒執行完畢,這個join()函式就執行完畢,主執行緒也就可以繼續運行了。
detach()函式
傳統多執行緒程式,主執行緒要等待子執行緒執行完畢,然後自己再退出。
deteach的意思是分離,也就是主執行緒不必和子執行緒匯合了,主執行緒與子執行緒各自執行。引入detach()是為了避免讓主執行緒逐個等待子執行緒結束。
joinable()函式
判斷是否可以成功使用join()或者detach(),返回true則可以,返回false則不可以。
最後的完整程式如下,您可以通過依次執行mythread.join(),mythread.detach()函式檢視程式執行結果以加深對這幾個函式的理解。
#include <iostream> #include <thread> using namespace std; void thread_function() { for(int i = 0; i < 5; i++) cout << "子執行緒執行" << i+1 << endl; } int main() { thread mythread(thread_function); // 傳遞初始函式作為執行緒的引數 if(mythread.joinable()) mythread.join(); // 使用join()函式阻塞主執行緒直至子執行緒執行完畢 if(mythread.joinable()) mythread.detach(); // 使用detach()函式讓子執行緒和主執行緒並行執行,主執行緒也不再等待子執行緒。 for(int i = 0; i < 5; i++) cout << "主執行緒執行" << i+1 << endl; return 0; }
4 執行結果分析
如果只使用join()函式,註釋detach()函式,執行結果如下,為順序執行:
如果只使用detach()函式,執行結果如下,每次執行的結果均不相同:
1.2 使用類物件建立執行緒
建立thread的時候引數不僅可以是一個函式,也可以是一個類的物件。這個類中需要過載運算子(),如下所示:
#include <iostream>
#include <thread>
using namespace std;
class Thread
{
public:
// 運算子過載
void operator()()
{
for(int i = 0; i < 5; i++)
cout << "子執行緒執行" << i+1 << endl;
}
};
int main()
{
Thread t;
thread mythread(t); // 傳遞初始函式作為執行緒的引數
if(mythread.joinable())
mythread.join(); // 使用join()函式阻塞主執行緒直至子執行緒執行完畢
if(mythread.joinable())
mythread.detach(); // 使用detach()函式讓子執行緒和主執行緒並行執行,主執行緒也不再等待子執行緒。
for(int i = 0; i < 5; i++)
cout << "主執行緒執行" << i+1 << endl;
return 0;
}
1.3 用Lambda表示式建立執行緒
在C++11中引入了lambda表示式,Lambda表示式完整的宣告格式如下:
[capture list] (params list) mutable exception-> return type { function body }
#include <iostream>
#include <thread>
using namespace std;
int main()
{
auto mylamthread = [] {
for(int i = 0; i < 5; i++)
cout << "子執行緒執行" << endl;
};
thread mythread(mylamthread); // 傳遞初始函式作為執行緒的引數
if(mythread.joinable())
mythread.join(); // 使用join()函式阻塞主執行緒直至子執行緒執行完畢
if(mythread.joinable())
mythread.detach(); // 使用detach()函式讓子執行緒和主執行緒並行執行,主執行緒也不再等待子執行緒。
for(int i = 0; i < 5; i++)
cout << "主執行緒執行" << i+1 << endl;
return 0;
}