日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Thread中,join()方法

發(fā)布時間:2025/3/21 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Thread中,join()方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

std::thread是c++11新引入的線程標準庫,通過其可以方便的編寫與平臺無關(guān)的多線程程序,雖然對比針對平臺來定制化多線程庫會使性能達到最大,但是會喪失了可移植性,這樣對比其他的高級語言,可謂是一個不足。終于在c++11承認多線程的標準,可謂可喜可賀!!!

在使用std::thread的時候,對創(chuàng)建的線程有兩種操作:等待/分離,也就是join/detach操作。join()操作是在std::thread t(func)后“某個”合適的地方調(diào)用,其作用是回收對應(yīng)創(chuàng)建的線程的資源,避免造成資源的泄露。detach()操作是在std::thread t(func)后馬上調(diào)用,用于把被創(chuàng)建的線程與做創(chuàng)建動作的線程分離,分離的線程變?yōu)楹笈_線程,其后,創(chuàng)建的線程的“死活”就與其做創(chuàng)建動作的線程無關(guān),它的資源會被init進程回收。

在這里主要對join做深入的理解。

由于join是等待被創(chuàng)建線程的結(jié)束,并回收它的資源。因此,join的調(diào)用位置就比較關(guān)鍵。比如,以下的調(diào)用位置都是錯誤的。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

void test()

{

}

?

bool do_other_things()

{

}

?

int main()

{

??std::thread t(test);

??int ret = do_other_things();

??if(ret == ERROR) {

????return -1;

??}

?

??t.join();

??return 0;

}

很明顯,如果do_other_things()函數(shù)調(diào)用返ERROR, 那么就會直接退出main函數(shù),此時join就不會被調(diào)用,所以線程t的資源沒有被回收,造成了資源泄露。

例子二:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

void test()

{

}

?

bool do_other_things()

{

}

?

int main()

{

??std::thread t(test);

?

??try {

????do_other_things();

??}

??catch(...) {

????throw;

??}

??t.join();

??return 0;

}

這個例子和例子一差不多,如果調(diào)用do_other_things()函數(shù)拋出異常,那么就會直接終止程序,join也不會被調(diào)用,造成了資源沒被回收。

那么直接在異常捕捉catch代碼塊里調(diào)用join就ok啦。

例子三:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

void test()

{

}

?

bool do_other_things()

{

}

?

int main()

{

??std::thread t(test);

?

??try {

????do_other_things();

??}

??catch(...) {

????t.join();

????throw;

??}

??t.join();

??return 0;

}

是不是很多人這樣操作?這樣做不是萬無一失的,?try/catch塊只能夠捕捉輕量級的異常錯誤,在這里如果在調(diào)用do_other_things()時發(fā)生嚴重的異常錯誤,那么catch不會被觸發(fā)捕捉異常,同時造成程序直接從函數(shù)調(diào)用棧回溯返回,也不會調(diào)用到j(luò)oin,也會造成線程資源沒被回收,資源泄露。

所以在這里有一個方法是使用創(chuàng)建局部對象,利用函數(shù)調(diào)用棧的特性,確保對象被銷毀時觸發(fā)析構(gòu)函數(shù)的方法來確保在主線程結(jié)束前調(diào)用join(),等待回收創(chuàng)建的線程的資源。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

class mythread {

private:

??std::thread &m_t;

?

public:

??explicit mythread(std::thread &t):m_t(t){}

??~mythread() {

????if(t.joinable()) {

??????t.join()

????}

??}

?

??mythread(mythread const&) = delete;

??mythread& operate=(mythread const&) = delete;

}

?

void test()

{

}

?

bool do_other_things()

{

}

?

int main()

{

??std::thread t(test);

??mythread q(t);

?

??if(do_other_things()) {

????return -1;

??}

?

??return 0;

}

在上面的例子中,無論在調(diào)用do_other_things()是發(fā)生錯誤,造成return main函數(shù),還是產(chǎn)生異常,由于函數(shù)調(diào)用棧的關(guān)系,總會回溯的調(diào)用局部對象q的析構(gòu)函數(shù),同時在q的析構(gòu)函數(shù)里面先判斷j.joinable()是因為join操作對于同一個線程只能調(diào)用一次,不然會出現(xiàn)錯誤的。這樣,就可以確保線程一定會在主函數(shù)結(jié)束前被等待回收了。

以上所述是小編給大家介紹的c++11中關(guān)于std::thread的join詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

您可能感興趣的文章:

  • C++11并發(fā)編程:多線程std::thread
  • C++11 并發(fā)指南之std::thread 詳解

總結(jié)

以上是生活随笔為你收集整理的Thread中,join()方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。