linux線程間通訊

來源:互聯網
上載者:User

線程間無需特別的手段進行通訊,因為線程間可以共用資料結構,也就是一個全域變數可以被兩個線程同時使用。不過要注意的是線程間需要做好同步,一般用mutex。可以參考一些比較新的UNIX/Linux編程的書,都會提到Posix線程編程,比如《UNIX環境進階編程(第二版)》、《UNIX系統編程》等等。 linux的訊息屬於IPC,也就是處理序間通訊,線程用不上。 

linux用pthread_kill對線程發訊號。 另:windows下不是用post..(你是說PostMessage嗎?)進行線程通訊的吧? 

windows用PostThreadMessage進行線程間通訊,但實際上極少用這種方法。還是利用同步多一些 LINUX下的同步和Windows原理都是一樣的。不過Linux下的singal中斷也很好用。 

用好訊號量,共用資源就可以了。 

 使用多線程的理由之一是和進程相比,它是一種非常"節儉"的多任務操作方式。我們知道,在Linux系統下,啟動一個新的進程必須分配給它獨立的地址空間,建立眾多的資料表來維護它的程式碼片段、堆棧段和資料區段,這是一種"昂貴"的多任務工作方式。而運行於一個進程中的多個線程,它們彼此之間使用相同的地址空間,共用大部分資料,啟動一個線程所花費的空間遠遠小於啟動一個進程所花費的空間,而且,線程間彼此切換所需的時間也遠遠小於進程間切換所需要的時間。

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

   首先在主函數中,我們使用到了兩個函數,pthread_create和pthread_join,並聲明了一個pthread_t型的變數。
pthread_t在標頭檔pthread.h中已經聲明,是線程的標示符

   函數pthread_create用來建立一個線程,函數原型:

extern int pthread_create __P ((pthread_t *__thread, __const pthread_attr_t *__attr,void *(*__start_routine) (void *), void *__arg));

  第一個參數為指向線程標識符的指標,第二個參數用來設定線程屬性,第三個參數是線程運行函數的起始地址,最後一個參數是運行函數的參數。若我們的函數thread不需要參數,所以最後一個參數設為空白指標。第二個參數我們也設為空白指標,這樣將產生預設屬性的線程。對線程屬性的設定和修改我們將在下一節闡述。當建立線程成功時,函數返回0,若不為0則說明建立線程失敗,常見的錯誤傳回碼為EAGAIN和EINVAL。前者表示系統限制建立新的線程,例如線程數目過多了;後者表示第二個參數代表的線程屬性值非法。建立線程成功後,新建立的線程則運行參數三和參數四確定的函數,原來的線程則繼續運行下一行代碼。 
函數pthread_join用來等待一個線程的結束。函數原型為:

  extern int pthread_join __P ((pthread_t __th, void **__thread_return));

  第一個參數為被等待的線程標識符,第二個參數為一個使用者定義的指標,它可以用來儲存被等待線程的傳回值。這個函數是一個線程阻塞的函數,調用它的函數將一直等待到被等待的線程結束為止,當函數返回時,被等待線程的資源被收回。一個線程的結束有兩種途徑,一種是象我們上面的例子一樣,函數結束了,調用它的線程也就結束了;另一種方式是通過函數pthread_exit來實現。它的函數原型為:

  extern void pthread_exit __P ((void *__retval)) __attribute__ ((__noreturn__));

  唯一的參數是函數的傳回碼,只要pthread_join中的第二個參數thread_return不是NULL,這個值將被傳遞給thread_return。最後要說明的是,一個線程不能被多個線程等待,否則第一個接收到訊號的線程成功返回,其餘調用pthread_join的線程則返回錯誤碼ESRCH。

2、修改線程的屬性
設定線程綁定狀態的函數為pthread_attr_setscope,它有兩個參數,第一個是指向屬性結構的指標,第二個是綁定類型,它有兩個取值:PTHREAD_SCOPE_SYSTEM(綁定的)和PTHREAD_SCOPE_PROCESS(非綁定的)。下面的代碼即建立了一個綁定的線程。 

#include 
pthread_attr_t attr;
pthread_t tid;

/*初始化屬性值,均設為預設值*/
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);

pthread_create(&tid, &attr, (void *) my_function, NULL);

3、線程的資料處理

和進程相比,線程的最大優點之一是資料的共用性,各個進程共用父進程處沿襲的資料區段,可以方便的獲得、修改資料。但這也給多線程編程帶來了許多問題。我們必須當心有多個不同的進程訪問相同的變數。許多函數是不可重新進入的,即同時不能運行一個函數的多個拷貝(除非使用不同的資料區段)。在函數中聲明的靜態變數常常帶來問題,函數的傳回值也會有問題。因為如果返回的是函數內部靜態聲明的空間的地址,則在一個線程調用該函數得到地址後使用該地址指向的資料時,別的線程可能調用此函數並修改了這一段資料。在進程中共用的變數必須用關鍵字volatile來定義,這是為了防止編譯器在最佳化時(如gcc中使用-OX參數)改變它們的使用方式。為了保護變數,我們必須使用訊號量、互斥等方法來保證我們對變數的正確使用。

4、互斥鎖

互斥鎖用來保證一段時間內只有一個線程在執行一段代碼。必要性顯而易見:假設各個線程向同一個檔案順序寫入資料,最後得到的結果一定是災難性的

 

  1. #define _GNU_SOURCE
  2. #include <unistd.h>
  3. #include <pthread.h>
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7.  
  8. //static pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
  9. // 這裡雖然是 P/V ,但是用 cond 確實更方便。
  10. static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  11. static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  12.  
  13. int i = 0;
  14.  
  15. void get ()
  16. {
  17. pthread_mutex_lock (&mutex);
  18. while ( i == 0 ) // 隊列下限
  19. pthread_cond_wait (&cond, &mutex); // 喚醒其它線程進行檢測。
  20.  
  21. --i;
  22. pthread_cond_signal (&cond);
  23. printf ("Current size: %d/n", i);
  24.  
  25. pthread_mutex_unlock (&mutex);
  26. }
  27.  
  28. void put ()
  29. {
  30. pthread_mutex_lock (&mutex);
  31. while ( i == 3 ) // 隊列上限
  32. pthread_cond_wait (&cond, &mutex);
  33.  
  34. ++i;
  35. pthread_cond_signal (&cond); // 喚醒其它線程
  36. printf ("Now size: %d/n", i);
  37.  
  38. pthread_mutex_unlock (&mutex);
  39. }
  40.  
  41. void *thf ( void *arg )
  42. {
  43. while ( 1 )
  44. {
  45. put ();
  46. }
  47. }
  48.  
  49. int main ()
  50. {
  51. pthread_t tid;
  52. pthread_create (&tid, NULL, thf, NULL);
  53.  
  54. sleep (3);
  55. while ( 1 )
  56. get ();
  57. }

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.