1. 程式人生 > >c++ thread(2.1)---join()

c++ thread(2.1)---join()

今天第一次接觸C++併發程式設計,工具用書是《C++併發程式設計實戰》,這本書翻譯的非常好,比較尊重原著。

側重join()函式的使用

先上程式碼:

#include<thread>
#include<iostream>
using namespace std;
void hello()
{
	cout << "szu 801 科技樓!"<<endl;
}
void do_something()
{
	cout << "wait for a minute!" << endl;
	hello();
}
struct MyStruct
{
	int i;
	MyStruct(int i_):i(i_){}
	void operator()()
	{
		for (unsigned j = 0;j < 100000; ++j)
		{
			do_something();
		}
	}
};

void oops()
{
	int some_local_state = 0;
	MyStruct my_struct(some_local_state);
	std::thread my_thread(my_struct);	 //啟動執行緒
	my_thread.detach();	  //不等待執行緒完成。函式退出
	//my_thread.join();//函式退出前,執行緒執行完畢
}
int main()
{
	oops();
	return 0;
}

(1)線上程啟動的時候,我們會涉及到呼叫執行緒的函式是等待執行緒結束後函式退出,還是不等待。如果不等待(detach()函式),那麼上述程式碼中的oops()函式的區域性變數函式結束銷燬後還在被執行緒使用,這是不可取的。我們呼叫join()表示等待執行緒結束在退出函式。

(2)join()函式簡單而粗暴,要麼等,要麼就是不等。呼叫join()函式的行為會清理所有與執行緒相關聯的儲存器,這樣該執行緒將不與任何其他的執行緒相關聯。一旦呼叫,該std::thread()是不可連線的。joinable()將返回false。

(3)如果要分離執行緒,那麼在啟動執行緒之後立即呼叫detach()。如果打算等待該執行緒,就要仔細選擇在哪個位置呼叫join()。

(4)但是問題出現了,如果線上程啟動之後但又在呼叫join()之前使用引發了異常,那麼join()呼叫就容易被跳過。這時候我們避免這種情況發生的有效方法之一是使用標準的資源獲取即初始化(RAII)慣用語法。並提供一個類,在他的解構函式中進行join()。

程式碼舉例:

class thread_guard	//使用RAII等待執行緒完成
{
	std::thread &t;
public:
	explicit thread_guard(std::thread &t_) :
		t(t_){}
	~thread_guard()
	{
		if (t.joinable()) //如果執行緒還沒結束
		{
			t.join();		 //就等待執行緒完成
		}
	}
	thread_guard(thread_guard const&) = delete;//禁止複製 宣告為已經被刪除了
	thread_guard operator=(thread_guard const&) = delete;//	禁止賦值操作	,
};
void f()
{
	int some_local_state = 0;
	MyStruct my_struct(some_local_state);
	std::thread t(my_struct);	 //啟動執行緒
	thread_guard g(t);
	do_something();	//執行到這裡時,區域性物件會按照解構函式逆序銷燬
}
int main()
{
	f();
/*<span style="white-space:pre">	</span>thread_guard a();
<span style="white-space:pre">	</span>thread_guard b(a);//這個操作是不合法的*/
	return 0;
}
(5)如果無需等待執行緒完成,可以通過呼叫detach()來避免這種異常的安全問題,這樣就確保thread物件被銷燬時,std::terminate()不會被呼叫,此時執行緒一般執行在後臺。

相關推薦

c++ thread(2.1)---join()

今天第一次接觸C++併發程式設計,工具用書是《C++併發程式設計實戰》,這本書翻譯的非常好,比較尊重原著。 側重join()函式的使用 先上程式碼: #include<thread> #include<iostream> using namespa

2C#,NPOI2.2.1,.NET 4.0 獲取單元格公式值,設置單元格的格式

idata .data icc == ted bsp taf shee else //獲取單元格的公式值 String temp; if (row.GetCell(0).CellType == CellType.Formula) temp = row.GetCell(0).

C++ Templates (2.1 類模板Stack的實現 Implementation of Class Template Stack)

[返回完整目錄](https://www.cnblogs.com/kaycharm/p/13433381.html#第一部分章節目錄) [toc] # 2.1 類模板Stack的實現 Implementation of Class Template Stack 正如函式模板,可以如下方式在一個頭檔案中宣

C# 彩色文件夾2.1.5

right 自動 統一管理 mage dds 管理器 icon 選擇 com 最新下載地址:https://pan.baidu.com/s/1c1FqYqs 具體介紹見官網MultiColorWin或者http://www.cnblogs.com/QQ818673

章節號比較排序(A.1、B.2.1C.4)

java 章節號 排序 private static int compareSerialNum(String str1,String str2){ if(str1.equals(str2)){ return 0; } if(!str1.contains(".")&

ParserError: Error tokenizing data. C error: Expected 1 fields in line 122, saw 2

txt文件 ces out reader txt parse erer aud expected 數據分析和挖掘實戰第15章的一段讀取.txt文件報錯 import pandas as pd inputfile = ‘data/meidi_jd.txt‘ outputf

2.16.4.內核啟動的C語言階段1

傳參 代碼 是我 驅動加載 語言 不同 整體 硬件 分析 本節講述內核學習的學習思路、學習方法和主體線路。本節課程的學習目的是讓大家對內核的特點和不同的學習思路有個認識。 2.16.4.1、這一塊的學習思路 (1)抓大放小,不深究. (2)感興趣可以就某個話題去網上搜索資料

MemSQL Start[c]UP 2.0 - Round 1 F - Permutation 思維+線段樹維護hash值

F - Permutation 思路:對於當前的值x, 只需要知道x + k, x - k這兩個值是否出現在其左右兩側,又因為每個值只有一個, 所以可以轉換成,x+k, x-k在到x所在位置的時候是否都出現,或者都不出現,即出現情況相等,我們可以 用線段樹維護hash值的方式來判斷所有x+k, 

MemSQL Start[c]UP 2.0 - Round 1 E - Three strings 廣義字尾自動機

E - Three strings 將三個串加進去,看每個節點在三個串中分別出現了多少次。 #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk mak

C語言計算:t=1-1/(2*2)-1/(3*3)-...-1/(m*m)

#include <stdio.h> #include <stdlib.h> #include <math.h> int main() {     int  m,i;     int n;  

C--計算求1+2!+3!+.......+n!

求1+2!+3!+.......+n! 程式碼; 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 /* run this program using the console pauser or add y

C藝術篇 1-2 二維數組

第一個元素 http 分享 默認 info 我們 src ron size 接下來討論二維數組。若有一個二維數組如下: int x[3][2] ={10,20,30,40,50,60}; 此數組共有六個元素(3行,2列),每一元素的地址為&x[0][0]、&

練習2-1 Programming in C is fun!

練習2-1 Programming in C is fun! 一 問題描述 本題要求編寫程式,輸出一個短句“Programming in C is fun!”。 輸入格式: 本題目沒有輸入。 輸出格式: 在一行中輸出短句“Programming in C is fun!

doctest 2.1.0 釋出,快速靈活的 C++ 測試框架

doctest 2.1.0 已釋出,更新內容: Closed issues: doctest::String ctor with non-zero terminated string #165 thread_local is not supported on iOS 9.0 

【HDU2582 關於 gcd( C[n][1],C[n][2],C[n][3],........C[n][n-1) 】

給出公式Gcd(n)=gcd(C[n][1],C[n][2],……,C[n][n-1]), 求f(n)= Gcd(3)+Gcd(4)+…+Gcd(i)+…+Gcd(n)。 關於組合數的最大公約數: gcd(C[n][1],C[n][2],C[n][3],........C[n][n-1) 當

C語言——兩種方法計算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值

方法一:首先我們先觀察這個數學式子的規律,可以發現奇數項均為正數,偶數項均為負數。則我們可以利用條件語句if來判斷奇偶,最後分別對奇數項和偶數項求和。 原始碼: #include<stdio.h> #include<stdlib.h> int main() {

pow函式(數學次方)在c語言的用法,兩種編寫方法例項( 計算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值)

關於c語言裡面pow函式,下面借鑑了某位博主的一篇文章: 標頭檔案:#include <math.h> pow() 函式用來求 x 的 y 次冪(次方),x、y及函式值都是double型 ,其原型為:    double pow(double x, double y

資料結構c語言版 嚴蔚敏(演算法2.1 將所有在Lb中但不在La中的元素插入到La中)

標頭檔案: c1.h (相關標頭檔案及函式結果狀態程式碼集合) /* c1.h (程式名) */ #include<string.h> #include<ctype.h> #include<malloc.h> /

c++中求1!+2!+3!+...+20!(不用遞迴)

c++中求1!+2!+3!+…+20!(不用遞迴) #include "stdafx.h" #include<iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) {

菜鳥的C++ 知識盲區(跌倒)到知識黑洞(放棄)---------2.1變數和基本型別

前言 說來話長,本人是一個不合格的程式設計師,最起碼我覺得我水平很菜。本科就讀於北方一個沒落的211,學的是機械設計製造及其自動化,基本上本科沒有接觸過什麼“高深”的關於程式設計的專案,不過稀裡糊塗計算機二級考過了,但是C語言並沒有學的很好,什麼指標啦只是大概知道。本科