執行緒間無需特別的手段進行通訊,因為執行緒間可以共享資料結構,也就是一個全域性變數可以被兩個執行緒同時使用,不過要注意的是執行緒間需要做好同步。
執行緒間無需特別的手段進行通訊,因為執行緒間可以共享資料結構,也就是一個全域性變數可以被兩個執行緒同時使用。不過要注意的是執行緒間需要做好同步,一般用mutex。可以參考一些比較新的UNIX/Linux程式設計的書,都會提到Posix執行緒程式設計,比如《UNIX環境高階程式設計(第二版)》、《UNIX系統程式設計》等等。 linux的訊息屬於IPC,也就是程序間通訊,執行緒用不上。
linux用pthread_kill對執行緒發訊號。 另:windows下不是用post..(你是說PostMessage嗎?)進行執行緒通訊的吧?
windows用PostThreadMessage進行執行緒間通訊,但實際上極少用這種方法。還是利用同步多一些 LINUX下的同步和Windows原理都是一樣的。不過Linux下的singal中斷也很好用。
用好訊號量,共享資源就可以了。
使用多執行緒的理由之一是和程序相比,它是一種非常"節儉"的多工操作方式。我們知道,在Linux系統下,啟動一個新的程序必須分配給它獨立的地址空間,建立眾多的資料表來維護它的程式碼段、堆疊段和資料段,這是一種"昂貴"的多工工作方式。而運行於一個程序中的多個執行緒,它們彼此之間使用相同的地址空間,共享大部分資料,啟動一個執行緒所花費的空間遠遠小於啟動一個程序所花費的空間,而且,執行緒間彼此切換所需的時間也遠遠小於程序間切換所需要的時間。
使用多執行緒的理由之二是執行緒間方便的
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));
第一個引數為被等待的執行緒識別符號,第二個引數為一個使用者定義的指標,它可以用來
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、互斥鎖
互斥鎖用來保證一段時間內只有一個執行緒在執行一段程式碼。必要性顯而易見:假設各個執行緒向同一個檔案順序寫入資料,最後得到的結果一定是災難性的