欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Linux操作系統下的多線程編程詳細解析

系統 1991 0

http://blog.csdn.net/ruglcc/article/details/7874076

zieckey? zieckey yahoo.com.cn

?? ?
線程( thread )技術早在 60 年代就被提出,但真正應用多線程到操作系統中去,是在 80 年代中期, solaris 是這方面的佼佼者。傳統的 Unix 也支持線程的概念,但是在一個進程( process )中只允許有一個線程,這樣多線程就意味著多進程。
現在,多線程技術已經被許多操作系統所支持,包括 Windows/NT ,當然,也包括 Linux

  為什么有了進程的概念后,還要再引入線程呢?使用多線程到底有哪些好處?什么的系統應該選用多線程?我們首先必須回答這些問題。

  使用多線程的理由之一是和進程相比,它是一種非常 " 節儉 " 的多任務操作方式。我們知道,在 Linux 系統下,啟動一個新的進程必須分配給它獨立的地址空間,建立眾多的數據表來維護它的代碼段、堆棧段和數據段,這是一種 " 昂貴 " 的多任務工作方式。而運行于一個進程中的多個線程,它們彼此之間使用相同的地址空間,共享大部分數據,啟動一個線程所花費的空間遠遠小于啟動一個進程所花費的空間,而且,線程間彼此切換所需的時間也遠遠小于進程間切換所需要的時間。據統計,總的說來,一個進程的開銷大約是一個線程開銷的 30 倍左右,當然,在具體的系統上,這個數據可能會有較大的區別。

  使用多線程的理由之二是線程間方便的通信機制。對不同進程來說,它們具有獨立的數據空間,要進行數據的傳遞只能通過通信的方式進行,這種方式不僅費時,而且很不方便。線程則不然,由于同一進程下的線程之間共享數據空間,所以一個線程的數據可以直接為其它線程所用,這不僅快捷,而且方便。當然,數據的共享也帶來其他一些問題,有的變量不能同時被兩個線程所修改,有的子程序中聲明為 static 的數據更有可能給多線程程序帶來災難性的打擊,這些正是編寫多線程程序時最需要注意的地方。

  除了以上所說的優點外,不和進程比較,多線程程序作為一種多任務、并發的工作方式,當然有以下的優點:

1)? 提高應用程序響應。這對圖形界面的程序尤其有意義,當一個操作耗時很長時,整個系統都會等待這個操作,此時程序不會響應鍵盤、鼠標、菜單的操作,而使用多線程技術,將耗時長的操作( time consuming )置于一個新的線程,可以避免這種尷尬的情況。

2)? 使多 CPU 系統更加有效。操作系統會保證當線程數不大于 CPU 數目時,不同的線程運行于不同的 CPU 上。

3)? 改善程序結構。一個既長又復雜的進程可以考慮分為多個線程,成為幾個獨立或半獨立的運行部分,這樣的程序會利于理解和修改。

  下面我們先來嘗試編寫一個簡單的多線程程序。

  簡單的多線程編程

Linux 系統下的多線程遵循 POSIX 線程接口,稱為 pthread 。編寫 Linux 下的多線程程序,需要使用頭文件 pthread.h ,連接時需要使用庫 libpthread.a 。順便說一下, Linux pthread 的實現是通過系統調用 clone ()來實現的。 clone ()是 Linux 所特有的系統調用,它的使用方式類似 fork ,關于 clone ()的詳細情況,有興趣的讀者可以去查看有關文檔說明。下面我們展示一個最簡單的多線程程序 pthread_create.c


一個重要的線程創建函數原型:
#include <pthread.h>
int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr, void *(*start_rtn)(void),void *restrict arg);

????
返回值:若是成功建立線程返回 0, 否則返回錯誤的編號
????
形式參數:
??????????????? pthread_t *restrict tidp?
要創建的線程的線程 id 指針
??????????????? const pthread_attr_t *restrict attr?
創建線程時的線程屬性
??????????????? void* (start_rtn)(void)?
返回值是 void 類型的指針函數
??????????????? void *restrict arg?? start_rtn
的行參
?????????????? ?
例程 1 ????????????????????????????????
????
功能:創建一個簡單的線程
????
程序名稱: pthread_create.c???????

  1. /******************************************************************************************** ?
  2. **????Name:pthread_create.c ?
  3. **????Used?to?study?the?multithread?programming?in?Linux?OS ?
  4. **????Author:zeickey ?
  5. **????Date:2006/9/16???????? ?
  6. **????Copyright?(c)?2006,All?Rights?Reserved! ?
  7. *********************************************************************************************/ ??
  8. ??
  9. #include?<stdio.h> ??
  10. #include?<pthread.h> ??
  11. ??
  12. void ?*myThread1( void )??
  13. {??
  14. ???? int ?i;??
  15. ???? for ?(i=0;?i<100;?i++)??
  16. ????{??
  17. ????????printf( "This?is?the?1st?pthread,created?by?zieckey./n" );??
  18. ????????sleep(1); //Let?this?thread?to?sleep?1?second,and?then?continue?to?run ??
  19. ????}??
  20. }??
  21. ??
  22. void ?*myThread2( void )??
  23. {??
  24. ???? int ?i;??
  25. ???? for ?(i=0;?i<100;?i++)??
  26. ????{??
  27. ????????printf( "This?is?the?2st?pthread,created?by?zieckey./n" );??
  28. ????????sleep(1);??
  29. ????}??
  30. }??
  31. ??
  32. int ?main()??
  33. {??
  34. ???? int ?i=0,?ret=0;??
  35. ????pthread_t?id1,id2;??
  36. ??????
  37. ????ret?=?pthread_create(&id2,?NULL,?( void *)myThread1,?NULL);??
  38. ???? if ?(ret)??
  39. ????{??
  40. ????????printf( "Create?pthread?error!/n" );??
  41. ???????? return ?1;??
  42. ????}??
  43. ??????
  44. ????ret?=?pthread_create(&id2,?NULL,?( void *)myThread2,?NULL);??
  45. ???? if ?(ret)??
  46. ????{??
  47. ????????printf( "Create?pthread?error!/n" );??
  48. ???????? return ?1;??
  49. ????}??
  50. ??????
  51. ????pthread_join(id1,?NULL);??
  52. ????pthread_join(id2,?NULL);??
  53. ??????
  54. ???? return ?0;??
  55. }??



  我們編譯此程序:
# gcc pthread_create.c -lpthread

因為 pthread 的庫不是 linux 系統的庫,所以在進行編譯的時候要加上 -lpthread ,否則編譯不過,會出現下面錯誤
thread_test.c:?
在函數 ?‘create’? 中:
thread_test.c:7:?
警告: ? 在有返回值的函數中,程序流程到達函數尾
/tmp/ccOBJmuD.o: In function `main':thread_test.c:(.text+0x4f)
:對 ‘pthread_create’ 未定義的引用
collect2: ld?
返回 ?1

  運行,我們得到如下結果:
# ./a.out?
This is the 1st pthread,created by zieckey.
This is the 2st pthread,created by zieckey.
This is the 1st pthread,created by zieckey.
This is the 2st pthread,created by zieckey.
This is the 2st pthread,created by zieckey.
This is the 1st pthread,created by zieckey.
....

兩個線程交替執行。
此例子介紹了創建線程的方法。
下面例子介紹向線程傳遞參數。


例程 2
????
功能:向新的線程傳遞整形值
????
程序名稱: pthread_int.c

  1. /******************************************************************************************** ?
  2. **????Name:pthread_int.c ?
  3. **????Used?to?study?the?multithread?programming?in?Linux?OS ?
  4. **????Pass?a?parameter?to?the?thread. ?
  5. **????Author:zeickey ?
  6. **????Date:2006/9/16???????? ?
  7. **????Copyright?(c)?2006,All?Rights?Reserved! ?
  8. *********************************************************************************************/ ??
  9. ??
  10. #include?<stdio.h> ??
  11. #include?<pthread.h> ??
  12. #include?<unistd.h> ??
  13. ??
  14. void ?*create( void ?*arg)??
  15. {??
  16. ???? int ?*num;??
  17. ????num=( int ?*)arg;??
  18. ????printf( "create?parameter?is?%d?/n" ,*num);??
  19. ???? return ?( void ?*)0;??
  20. }??
  21. int ?main( int ?argc?, char ?*argv[])??
  22. {??
  23. ????pthread_t?tidp;??
  24. ???? int ?error;??
  25. ??????
  26. ???? int ?test=4;??
  27. ???? int ?*attr=&test;??
  28. ??????
  29. ????error=pthread_create(&tidp,NULL,create,( void ?*)attr);??
  30. ??
  31. ???? if (error)??
  32. ????????{??
  33. ????????printf( "pthread_create?is?created?is?not?created?...?/n" );??
  34. ???????? return ?-1;??
  35. ????????}??
  36. ????sleep(1);??
  37. ????printf( "pthread_create?is?created?.../n" );??
  38. ???? return ?0;??????????
  39. }??



???? 編譯方法:

gcc -lpthread pthread_int.c -Wall


????
執行結果:

create parameter is 4
pthread_create is created is? created ...


????
例程總結:
????
可以看出來,我們在 main 函數中傳遞的整行指針,傳遞到我們新建的線程函數中。
????
在上面的例子可以看出來我們向新的線程傳入了另一個線程的 int 數據,線程之間還可以傳遞字符串或是更復雜的數據結構。


例程 3
????
程序功能:向新建的線程傳遞字符串
??? ????
程序名稱: pthread_string.c

  1. /******************************************************************************************** ?
  2. **????Name:pthread_string.c ?
  3. **????Used?to?study?the?multithread?programming?in?Linux?OS ?
  4. **????Pass?a?‘char*‘?parameter?to?the?thread. ?
  5. **????Author:zeickey ?
  6. **????Date:2006/9/16???????? ?
  7. **????Copyright?(c)?2006,All?Rights?Reserved! ?
  8. *********************************************************************************************/ ??
  9. #include?<pthread.h> ??
  10. #include?<stdio.h> ??
  11. #include?<unistd.h> ??
  12. ??
  13. void ?*create( void ?*arg)??
  14. {??
  15. ???? char ?*name;??
  16. ????name=( char ?*)arg;??
  17. ????printf( "The?parameter?passed?from?main?function?is?%s??/n" ,name);??
  18. ???? return ?( void ?*)0;??
  19. }??
  20. ??
  21. int ?main( int ?argc,? char ?*argv[])??
  22. {??
  23. ???? char ?*a= "zieckey" ;??
  24. ???? int ?error;??
  25. ????pthread_t?tidp;??
  26. ??
  27. ????error=pthread_create(&tidp,?NULL,?create,?( void ?*)a);??
  28. ??
  29. ???? if (error!=0)??
  30. ????{??
  31. ????????printf( "pthread?is?not?created./n" );??
  32. ???????? return ?-1;??
  33. ????}??
  34. ????sleep(1);??
  35. ????printf( "pthread?is?created...?/n" );??
  36. ???? return ?0;??
  37. }????


??
?? 編譯方法:

gcc -Wall pthread_string.c -lpthread


????
執行結果:
The parameter passed from main function is zieckey??
pthread is created...?


????
例程總結:
????
可以看出來 main 函數中的字符串傳入了新建的線程中。

例程 4
????
程序功能:向新建的線程傳遞字符串
??? ????
程序名稱: pthread_struct.c

  1. /******************************************************************************************** ?
  2. **????Name:pthread_struct.c ?
  3. **????Used?to?study?the?multithread?programming?in?Linux?OS ?
  4. **????Pass?a?‘char*‘?parameter?to?the?thread. ?
  5. **????Author:zeickey ?
  6. **????Date:2006/9/16???????? ?
  7. **????Copyright?(c)?2006,All?Rights?Reserved! ?
  8. *********************************************************************************************/ ??
  9. #include?<stdio.h> ??
  10. #include?<pthread.h> ??
  11. #include?<unistd.h> ??
  12. #include?<stdlib.h> ??
  13. ??
  14. struct ?menber??
  15. {??
  16. ???? int ?a;??
  17. ???? char ?*s;??
  18. };??
  19. ??
  20. void ?*create( void ?*arg)??
  21. {??
  22. ???? struct ?menber?*temp;??
  23. ????temp=( struct ?menber?*)arg;??
  24. ????printf( "menber->a?=?%d??/n" ,temp->a);??
  25. ????printf( "menber->s?=?%s??/n" ,temp->s);??
  26. ???? return ?( void ?*)0;??
  27. }??
  28. ??
  29. int ?main( int ?argc, char ?*argv[])??
  30. {??
  31. ????pthread_t?tidp;??
  32. ???? int ?error;??
  33. ???? struct ?menber?*b;??
  34. ????b=( struct ?menber?*)malloc(? sizeof ( struct ?menber)?);??
  35. ????b->a?=?4;??
  36. ????b->s?=? "zieckey" ;??
  37. ??
  38. ????error?=?pthread_create(&tidp,?NULL,?create,?( void ?*)b);??
  39. ??
  40. ???? if (?error?)??
  41. ????{??
  42. ????????printf( "phread?is?not?created.../n" );??
  43. ???????? return ?-1;??
  44. ????}??
  45. ????sleep(1);??
  46. ????printf( "pthread?is?created.../n" );??
  47. ???? return ?0;??
  48. }??




?? 編譯方法:

gcc -Wall pthread_struct.c -lpthread


????
執行結果:
menber->a = 4??
menber->s = zieckey??
pthread is created...

????
例程總結:
????
可以看出來 main 函數中的一個結構體傳入了新建的線程中。
????
線程包含了標識進程內執行環境必須的信息。他集成了進程中的所有信息都是對線程進行共享的,包括文本程序、程序的全局內存和堆內存、棧以及文件描述符。
????

例程 5
????
程序目的:驗證新建立的線程可以共享進程中的數據
????
程序名稱: pthread_share.c??

  1. /******************************************************************************************** ?
  2. **????Name:pthread_share_data.c ?
  3. **????Used?to?study?the?multithread?programming?in?Linux?OS ?
  4. **????Pass?a?‘char*‘?parameter?to?the?thread. ?
  5. **????Author:zeickey ?
  6. **????Date:2006/9/16???????? ?
  7. **????Copyright?(c)?2006,All?Rights?Reserved! ?
  8. *********************************************************************************************/ ??
  9. #include?<stdio.h> ??
  10. #include?<pthread.h> ??
  11. #include?<unistd.h> ??
  12. ??
  13. static ? int ?a=4;??
  14. void ?*create( void ?*arg)??
  15. {??
  16. ????printf( "new?pthread?...?/n" );??
  17. ????printf( "a=%d??/n" ,a);??
  18. ???? return ?( void ?*)0;??
  19. }??
  20. ??
  21. int ?main( int ?argc, char ?*argv[])??
  22. {??
  23. ????pthread_t?tidp;??
  24. ???? int ?error;??
  25. ??????
  26. ????a=5;??
  27. ??
  28. ????error=pthread_create(&tidp,?NULL,?create,?NULL);??
  29. ??
  30. ???? if (error!=0)??
  31. ????{??
  32. ????????printf( "new?thread?is?not?create?...?/n" );??
  33. ???????? return ?-1;??
  34. ????}??
  35. ??????
  36. ????sleep(1);??
  37. ??????
  38. ????printf( "new?thread?is?created?...?/n" );??
  39. ???? return ?0;??
  40. }??


? ??
?? 編譯方法:

gcc -Wall pthread_share_data.c -lpthread


????
執行結果:
new pthread ...?
a=5??
new thread is created ...?

? ??
例程總結:

可以看出來,我們在主線程更改了我們的全局變量 a 的值的時候,我們新建立的線程則打印出來了改變的值,可以看出可以訪問線程所在進程中的數據信息

2 、線程的終止

????
如果進程中任何一個線程中調用 exit _Exit, 或者是 _exit ,那么整個進程就會終止,
????
與此類似,如果信號的默認的動作是終止進程,那么,把該信號發送到線程會終止進程。
????
線程的正常退出的方式:
?????? (1)?
線程只是從啟動例程中返回,返回值是線程中的退出碼
?????? (2)?
線程可以被另一個進程進行終止
?????? (3)?
線程自己調用 pthread_exit 函數
????
兩個重要的函數原型:

#include <pthread.h>
void pthread_exit(void *rval_ptr);
/*rval_ptr?
線程退出返回的指針 */

int pthread_join(pthread_t thread,void **rval_ptr);
?? /*
成功結束進程為 0, 否則為錯誤編碼 */


????
例程 6
????
程序目的:線程正常退出,接受線程退出的返回碼
????
程序名稱: pthread_exit.c

  1. /******************************************************************************************** ?
  2. **????Name:pthread_exit.c ?
  3. **????Used?to?study?the?multithread?programming?in?Linux?OS ?
  4. **????A?example?showing?a?thread?to?exit?and?with?a?return?code. ?
  5. **????Author:zeickey ?
  6. **????Date:2006/9/16???????? ?
  7. **????Copyright?(c)?2006,All?Rights?Reserved! ?
  8. *********************************************************************************************/ ??
  9. ??
  10. #include?<stdio.h> ??
  11. #include?<pthread.h> ??
  12. #include?<unistd.h> ??
  13. ??
  14. void ?*create( void ?*arg)??
  15. {??
  16. ????printf( "new?thread?is?created?...?/n" );??
  17. ???? return ?( void ?*)8;??
  18. }??
  19. ??
  20. int ?main( int ?argc, char ?*argv[])??
  21. {??
  22. ????pthread_t?tid;??
  23. ???? int ?error;??
  24. ???? void ?*temp;??
  25. ??
  26. ????error?=?pthread_create(&tid,?NULL,?create,?NULL);??
  27. ??
  28. ???? if (?error?)??
  29. ????{??
  30. ????????printf( "thread?is?not?created?...?/n" );??
  31. ???????? return ?-1;??
  32. ????}??
  33. ????error?=?pthread_join(tid,?&temp);??
  34. ??
  35. ???? if (?error?)??
  36. ????{??
  37. ????????printf( "thread?is?not?exit?...?/n" );??
  38. ???????? return ?-2;??
  39. ????}??
  40. ??????
  41. ????printf( "thread?is?exit?code?%d?/n" ,?( int ?)temp);??
  42. ???? return ?0;??
  43. }??



?? 編譯方法:

gcc -Wall pthread_exit.c -lpthread


????
執行結果:
new thread is created ...
thread is exit code 8

????
例程總結:
可以看出來,線程退出可以返回線程的 int 數值。線程退出不僅僅可以返回線程的 int 數值,還可以返回一個復雜的數據結構。

????
例程 7
????
程序目的:線程結束返回一個復雜的數據結構
????
程序名稱: pthread_return_struct.c

  1. #include?<stdio.h> ??
  2. #include?<pthread.h> ??
  3. #include?<unistd.h> ??
  4. ??
  5. struct ?menber??
  6. {??
  7. ???? int ?a;??
  8. ???? char ?*b;??
  9. }temp={8, "zieckey" };??
  10. void ?*create( void ?*arg)??
  11. {??
  12. ????printf( "new?thread?...?/n" );??
  13. ???? return ?( void ?*)&temp;??
  14. }??
  15. ??
  16. int ?main( int ?argc, char ?*argv[])??
  17. {??
  18. ???? int ?error;??
  19. ????pthread_t?tid;??
  20. ???? struct ?menber?*c;??
  21. ??
  22. ????error?=?pthread_create(&tid,?NULL,?create,?NULL);??
  23. ??????
  24. ???? if (?error?)??
  25. ????{??
  26. ????????printf( "new?thread?is?not?created?...?/n" );??
  27. ???????? return ?-1;??
  28. ????}??
  29. ????printf( "main?...?/n" );??
  30. ??
  31. ????error?=?pthread_join(tid,( void ?*)&c);??
  32. ??
  33. ???? if (?error?)??
  34. ????{??
  35. ????????printf( "new?thread?is?not?exit?...?/n" );??
  36. ???????? return ?-2;??
  37. ????}??
  38. ????printf( "c->a?=?%d??/n" ,c->a);??
  39. ????printf( "c->b?=?%s??/n" ,c->b);??
  40. ????sleep(1);??
  41. ???? return ?0;??
  42. }??



?? 編譯方法:

gcc -Wall pthread_return_struct.c -lpthread


????
執行結果:

main ...
new thread ...
c->a = 8
c->b = zieckey


例程總結:
一定要記得返回的數據結構要是在這個數據要返回的結構沒有釋放的時候應用, 如果數據結構已經發生變化,那返回的就不會是我們所需要的,而是臟數據

3 、線程標識

????
函數原型:
? ?
#include <pthread.h>
pthread_t pthread_self(void);

pid_t getpid(void);
??? getpid()
用來取得目前進程的進程識別碼 , 函數說明

????
例程 8
????
程序目的:實現在新建立的線程中打印該線程的 id 和進程 id
????
程序名稱: pthread_id.c
???

  1. /******************************************************************************************** ?
  2. **????Name:pthread_id.c ?
  3. **????Used?to?study?the?multithread?programming?in?Linux?OS. ?
  4. **????Showing?how?to?get?the?thread's?tid?and?the?process's?pid. ?
  5. **????Author:zeickey ?
  6. **????Date:2006/9/16???????? ?
  7. **????Copyright?(c)?2006,All?Rights?Reserved! ?
  8. *********************************************************************************************/ ??
  9. #include?<stdio.h> ??
  10. #include?<pthread.h> ??
  11. #include?<unistd.h>?/*getpid()*/ ??
  12. ??
  13. void ?*create( void ?*arg)??
  14. {??
  15. ????printf( "New?thread?....?/n" );??
  16. ????printf( "This?thread's?id?is?%u??/n" ,?(unsigned? int )pthread_self());??
  17. ????printf( "The?process?pid?is?%d??/n" ,getpid());??
  18. ???? return ?( void ?*)0;??
  19. }???
  20. ??
  21. int ?main( int ?argc, char ?*argv[])??
  22. {??
  23. ????pthread_t?tid;??
  24. ???? int ?error;??
  25. ??
  26. ????printf( "Main?thread?is?starting?...?/n" );??
  27. ??
  28. ????error?=?pthread_create(&tid,?NULL,?create,?NULL);??
  29. ??
  30. ???? if (error)??
  31. ????{??
  32. ????????printf( "thread?is?not?created?...?/n" );??
  33. ???????? return ?-1;??
  34. ????}??
  35. ????printf( "The?main?process's?pid?is?%d??/n" ,getpid());??
  36. ????sleep(1);??
  37. ???? return ?0;??
  38. }??




???? 編譯方法:

???
gcc -Wall -lpthread pthread_id.c

????
執行結果:

Main thread is starting ...?
The main process's pid is 3307??
New thread ....?
This thread's id is 3086347152??
The process pid is 3307?


函數原型:

? ?#include <pthread.h>
void pthread_cleanup_push(void (*rtn)(void *),void *arg);
????
函數 rtn 是清理函數, arg 是調用參數

void pthread_cleanup_pop(int execute);
??
? ??
在前面講過線程的終止方式,是正常終止還是非正常終止,都會存在一個資源釋放的問題,在 posix 中提供了一組,就是我們上面看的函數進行線程退出的處理函數,有些像在進程中的 atexit 函數。釋放的方式是指 pthread_cleanup_push 的調用點到 pthread_cleanup_pop 之間程序段進行終止。

??? pthread_cleanup_push()/pthread_cleanup_pop
采用先入后出的方式的棧的管理方式, void *rtn(void *), 在執行 pthread_cleanup_push() 時壓入函數棧,多次執行 pthread_cleanup_push() 形成一個函數鏈,在執行這個函數鏈的時候會以反方向彈出,即先入后出。 execute 參數表識,是否執行彈出清理函數,當 execute=0 時不進行彈出清理函數,非零的時候彈出處理函數。

????
例程 9

????
程序目的:實現在正常結束線程的時候,進行函數處理

????
程序名稱: pthread_clean.c

?

  1. /******************************************************************************************** ?
  2. **????Name:pthread_clean.c ?
  3. **????Used?to?study?the?multithread?programming?in?Linux?OS ?
  4. **????A?example?showing?a?thread?to?be?cleaned. ?
  5. **????Author:zeickey ?
  6. **????Date:2008/6/28???????? ?
  7. **????Copyright?(c)?2006,All?Rights?Reserved! ?
  8. *********************************************************************************************/ ??
  9. #include?<stdio.h> ??
  10. #include?<pthread.h> ??
  11. #include?<unistd.h> ??
  12. void ?*clean( void ?*arg)??
  13. {??
  14. ????printf( "cleanup?:%s??/n" ,( char ?*)arg);??
  15. ???? return ?( void ?*)0;??
  16. }??
  17. void ?*thr_fn1( void ?*arg)??
  18. {??
  19. ????printf( "thread?1?start??/n" );??
  20. ????pthread_cleanup_push(?( void *)clean, "thread?1?first?handler" );??
  21. ????pthread_cleanup_push(?( void *)clean, "thread?1?second?hadler" );??
  22. ????printf( "thread?1?push?complete??/n" );??
  23. ???? if (arg)??
  24. ????{??
  25. ???????? return (( void ?*)1);??
  26. ????}??
  27. ????pthread_cleanup_pop(0);??
  28. ????pthread_cleanup_pop(0);??
  29. ???? return ?( void ?*)1;??
  30. }??
  31. void ?*thr_fn2( void ?*arg)??
  32. {??
  33. ????printf( "thread?2?start??/n" );??
  34. ????pthread_cleanup_push(?( void *)clean, "thread?2?first?handler" );??
  35. ????pthread_cleanup_push(?( void *)clean, "thread?2?second?handler" );??
  36. ????printf( "thread?2?push?complete??/n" );??
  37. ???? if (arg)??
  38. ????{??
  39. ????????pthread_exit(( void ?*)2);??
  40. ????}??
  41. ????pthread_cleanup_pop(0);??
  42. ????pthread_cleanup_pop(0);??
  43. ????pthread_exit(( void ?*)2);??
  44. }??
  45. int ?main( void )??
  46. {??
  47. ???? int ?err;??
  48. ????pthread_t?tid1,tid2;??
  49. ???? void ?*tret;??
  50. ??
  51. ????err=pthread_create(&tid1,NULL,thr_fn1,( void ?*)1);??
  52. ???? if (err!=0)??
  53. ????{??
  54. ????????printf( "error?....?/n" );??
  55. ???????? return ?-1;??
  56. ????}??
  57. ????err=pthread_create(&tid2,NULL,thr_fn2,( void ?*)1);??
  58. ??
  59. ???? if (err!=0)??
  60. ????{??
  61. ????????printf( "error?....?/n" );??
  62. ???????? return ?-1;??
  63. ????}??
  64. ????err=pthread_join(tid1,&tret);??
  65. ???? if (err!=0)??
  66. ????{??
  67. ????????printf( "error?....?/n" );??
  68. ???????? return ?-1;??
  69. ????}??
  70. ????printf( "thread?1?exit?code?%d??/n" ,( int )tret);??
  71. ??
  72. ????err=pthread_join(tid2,&tret);??
  73. ???? if (err!=0)??
  74. ????{??
  75. ????????printf( "error?....?" );??
  76. ???????? return ?-1;??
  77. ????}??
  78. ??
  79. ????printf( "thread?2?exit?code?%d??/n" ,( int )tret);??
  80. ??????
  81. ???? return ?1;??
  82. }??



???? 編譯方法:


?gcc -Wall -lpthread pthread_clean.c

????
執行結果:

thread 1 start??
thread 1 push complete??
thread 1 exit code 1??
thread 2 start??
thread 2 push complete??
cleanup :thread 2 second handler??
cleanup :thread 2 first handler??
thread 2 exit code 2?

pthread_join
? ?
SYNOPSIS
? ? ? ?#include <pthread.h>


? ? ? ?int pthread_join(pthread_t thread, void **rval_ptr);


DESCRIPTION
? ? ? ?The ?pthread_join() ?function shall suspend execution of the calling thread until the target thread terminates, unless the target thread has already termi-nated. On return from a successful pthread_join() call with a non-NULL value_ptr argument, the value passed to pthread_exit() ?by ?the ?terminating ?thread shall ?be ?made ?available ?in the location referenced by rval_ptr. When a pthread_join() returns successfully, the target thread has been terminated. The results of multiple simultaneous calls to pthread_join() specifying the same target thread are undefined. If the thread calling pthread_join() is canceled, then the target thread shall not be detached.
pthread_join用于掛起當前線程(調用pthread_join的線程),直到thread指定的線程終止運行為止,當前線程才繼續執行。thread指定的線程的返回值由rval_ptr返回。一個線程所使用的資源在對該線程調用pthread_join之前不會被重新分配,因此對于每個切入的線程必須調用一次pthread_join函數。線程必須可切入的而不是處于被分離狀態,并且其他線程不能對同一線程再次應用pthread_join調用。通過pthread_create調用中使用一個適當的attr參數或者調用pthread_detach可以讓一個線程處于被分離狀態。




? ?
SYNOPSIS
? ? ? ?#include <pthread.h>


? ? ? ?int pthread_join(pthread_t thread, void **rval_ptr);


DESCRIPTION
? ? ? ?The ?pthread_join() ?function shall suspend execution of the calling thread until the target thread terminates, unless the target thread has already termi-nated. On return from a successful pthread_join() call with a non-NULL value_ptr argument, the value passed to pthread_exit() ?by ?the ?terminating ?thread shall ?be ?made ?available ?in the location referenced by rval_ptr. When a pthread_join() returns successfully, the target thread has been terminated. The results of multiple simultaneous calls to pthread_join() specifying the same target thread are undefined. If the thread calling pthread_join() is canceled, then the target thread shall not be detached.
pthread_join用于掛起當前線程(調用pthread_join的線程),直到thread指定的線程終止運行為止,當前線程才繼續執行。thread指定的線程的返回值由rval_ptr返回。一個線程所使用的資源在對該線程調用pthread_join之前不會被重新分配,因此對于每個切入的線程必須調用一次pthread_join函數。線程必須可切入的而不是處于被分離狀態,并且其他線程不能對同一線程再次應用pthread_join調用。通過pthread_create調用中使用一個適當的attr參數或者調用pthread_detach可以讓一個線程處于被分離狀態。

  1. /******************************************************************************************** ?
  2. **????Name:pthread_join.c ?
  3. **????Used?to?study?the?multithread?programming?in?Linux?OS ?
  4. **????A?example?showing?a?thread?to?be?waited?to?end. ?
  5. **????Author:zeickey ?
  6. **????Date:2008/6/28???????? ?
  7. **????Copyright?(c)?2006,All?Rights?Reserved! ?
  8. *********************************************************************************************/ ??
  9. ??
  10. #include?<pthread.h> ??
  11. #include?<unistd.h> ??
  12. #include?<stdio.h> ??
  13. void ?* thread ( void ?*str)??
  14. {??
  15. ???? int ?i;??
  16. ???? for ?(i?=?0;?i?<?10;?++i)??
  17. ????{??
  18. ????????sleep(2);??
  19. ????????printf(? "This?in?the?thread?:?%d/n" ?,?i?);??
  20. ????}??
  21. ???? return ?NULL;??
  22. }??
  23. ??
  24. int ?main()??
  25. {??
  26. ????pthread_t?pth;??
  27. ???? int ?i;??
  28. ???? int ?ret?=?pthread_create(&pth,?NULL,? thread ,?( void ?*)(i));??
  29. ??????
  30. ????pthread_join(pth,?NULL);??
  31. ???? for ?(i?=?0;?i?<?10;?++i)??
  32. ????{??
  33. ????????sleep(1);??
  34. ????????printf(? "This?in?the?main?:?%d/n" ?,?i?);??
  35. ????}??
  36. ??????
  37. ???? return ?0;??
  38. }??


"pthread_join(pth, NULL);"這一行注釋掉:
[root@localhost src]# gcc pthread_join.c -lpthread
[root@localhost src]# ./a.out
This in the main : 0
This in the thread : 0
This in the main : 1
This in the main : 2
This in the thread : 1
This in the main : 3
This in the main : 4
This in the thread : 2
This in the main : 5
This in the main : 6
This in the thread : 3
This in the main : 7
This in the main : 8
This in the thread : 4
This in the main : 9


子線程還沒有執行完畢,main函數已經退出,那么子線程也就退出了。


“pthread_join(pth, NULL);”起作用
[root@localhost src]# gcc pthread_join.c -lpthread
[root@localhost src]# ./a.out
This in the thread : 0
This in the thread : 1
This in the thread : 2
This in the thread : 3
This in the thread : 4
This in the thread : 5
This in the thread : 6
This in the thread : 7
This in the thread : 8
This in the thread : 9
This in the main : 0
This in the main : 1
This in the main : 2
This in the main : 3
This in the main : 4
This in the main : 5
This in the main : 6
This in the main : 7
This in the main : 8
This in the main : 9
[root@localhost src]#


這說明pthread_join函數的調用者在等待子線程退出后才繼續執行

Linux操作系統下的多線程編程詳細解析


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 天天干电影| 欧美成人午夜免费完成 | 免费看av的网址 | 久久国产精品99久久久久久牛牛 | 亚洲欧美日韩中文字幕在线不卡 | 污视频在线免费 | 欧美一区二区三区久久 | 99成人精品视频 | 欧美在线一区二区三区 | 日韩小视频| 色婷婷综合久久久中字幕精品久久 | 白白操在线视频 | 久草热在线视频 | 色喜亚洲美女沟沟炮交国模 | 国产香蕉免费精品视频 | 日韩欧美不卡 | 亚洲一区二区三区在线播放 | 国产精品久久久久9999高清 | 天天操夜夜操 | 国产精品福利视频手机免费观看 | 日韩av成人 | 久草com | 久久观看 | 精品91久久 | 国产成人+综合亚洲+天堂 | 美女狠狠干 | 亚洲欧洲另类 | 婷婷亚洲五月 | 成人片网址 | v11av在线播放 | 国产一区二区精品在线 | 亚洲一区二区在线视频 | 91麻豆国产极品在线观看洋子 | 亚洲成人激情av | 激情六月天 | 国产精品1区2区3区 一级电影免费 | 色插视频 | 婷婷丁香社区 | 五月天香蕉 | 欧美一区二区三区在线观看免费 | 久久久久久影院 |