pthread多執行緒程式設計整理(二)

2021-04-27 19:51:39 字數 2602 閱讀 5232

補充:在傳統的unix模型中,當乙個程序需要由另乙個實體執行某件事時,該程序派生(fork)乙個子程序,讓子程序去進行處理。unix下的大多數網路伺服器程式都是這麼編寫的,即父程序接受連線,派生子程序,子程序處理與客戶的互動。

雖然這種模型很多年來使用得很好,但是fork時有一些問題:

1. fork是昂貴的。記憶體映像要從父程序拷貝到子程序,所有描述字要在子程序中複製等等。目前有的unix實現使用一種叫做寫時拷貝(copy-on-write)的技術,可避免父程序資料空間向子程序的拷貝。儘管有這種優化技術,fork仍然是昂貴的。

2. fork子程序後,需要用程序間通訊(ipc)在父子程序之間傳遞資訊。fork之前的資訊容易傳遞,因為子程序從一開始就有父程序資料空間及所有描述字的拷貝。但是從子程序返回資訊給父程序需要做更多的工作。

執行緒有助於解決這兩個問題。執行緒有時被稱為輕權程序(lightweight process),因為執行緒比程序「輕權」,一般來說,建立乙個執行緒要比建立乙個程序快10~100倍。

乙個程序中的所有執行緒共享相同的全域性記憶體,這使得執行緒很容易共享資訊,但是這種簡易性也帶來了同步問題。

乙個程序中的所有執行緒不僅共享全域性變數,而且共享:程序指令、大多數資料、開啟的檔案(如描述字)、訊號處理程式和訊號處置、當前工作目錄、使用者id和組id。但是每個執行緒有自己的執行緒id、暫存器集合(包括程式計數器和棧指標)、棧(用於存放區域性變數和返回位址)、error、訊號掩碼、優先順序。在linux中線程程式設計符合posix.1標準,稱為pthreads。所有的pthread函式都以pthread_開頭。以下先講述5個基本執行緒函式,在呼叫它們前均要包括pthread.h標頭檔案。然後再給出用它們編寫的乙個tcp客戶/伺服器程式例子。

第乙個函式:

int pthread_create (pthread_t *tid,const pthread_attr_t *attr,void *      (*func)(void *),void *arg);

乙個程序中的每個執行緒都由乙個執行緒id(thread id)標識,其資料型別是pthread_t(常常是unsigned int)。如果新的執行緒建立成功,其id將通過tid指標返回。

每個執行緒都有很多屬性:優先順序、起始棧大小、是否應該是乙個守護執行緒等等,當建立執行緒時,我們可通過初始化乙個pthread_attr_t變數說明這些屬性以覆蓋預設值。我們通常使用預設值,在這種情況下,我們將attr引數說明為空指標。

最後,當建立乙個執行緒時,我們要說明乙個它將執行的函式。執行緒以呼叫該函式開始,然後或者顯式地終止(呼叫pthread_exit)或者隱式地終止(讓該函式返回)。函式的位址由func引數指定,該函式的呼叫引數是乙個指標arg,如果我們需要多個呼叫引數,我們必須將它們打包成乙個結構,然後將其位址當作唯一的引數傳遞給起始函式。

在func和arg的宣告中,func函式取乙個通用指標(void *)引數,並返回乙個通用指標(void *),這就使得我們可以傳遞乙個指標(指向任何我們想要指向的東西)給執行緒,由執行緒返回乙個指標(同樣指向任何我們想要指向的東西)。呼叫成功,返回0,出錯時返回正e***值。pthread函式不設定errno。

第二個函式:

int pthread_join(pthread_t tid,void **status);

該函式等待乙個執行緒終止。把執行緒和程序相比,pthread_creat類似於fork,而pthread_join類似於waitpid。我們必須要等待執行緒的tid,很可惜,我們沒有辦法等待任意乙個執行緒結束。如果status指標非空,執行緒的返回值(乙個指向某個物件的指標)將存放在status指向的位置。

第三個函式:

pthread_t pthread_self(void);

執行緒都有乙個id以在給定的程序內標識自己。執行緒id由pthread_creat返回,我們可以pthread_self取得自己的執行緒id。

第四個函式:

intpthread_detach(pthread_t tid);

執行緒或者是可匯合的(joinable)或者是脫離的(detached)。當可匯合的執行緒終止時,其執行緒id和退出狀態將保留,直到另外乙個執行緒呼叫pthread_join。脫離的執行緒則像守護程序:當它終止時,所有的資源都釋放,我們不能等待它終止。如果乙個執行緒需要知道另乙個執行緒什麼時候終止,最好保留第二個執行緒的可匯合性。pthread_detach函式將指定的執行緒變為脫離的。該函式通常被想脫離自己的執行緒呼叫,如:pthread_detach(pthread_self ( ));

第五個函式:

void pthread_exit(void *status);

該函式終止執行緒。如果執行緒未脫離,其執行緒id和退出狀態將一直保留到呼叫程序中的某個其他執行緒呼叫pthread_join函式。指標status不能指向區域性於呼叫執行緒的物件,因為執行緒終止時這些物件也消失。有兩種其他方法可使執行緒終止:

1. 啟動執行緒的函式(pthread_creat的第3個引數)返回。既然該函式必須說明為返回乙個void指標,該返回值便是執行緒的終止狀態。

2. 如果程序的main函式返回或者任何執行緒呼叫了exit,程序將終止,執行緒將隨之終止。

pthread 多執行緒

多執行緒程式指的是在同乙個程式中多個執行流併發執行,它們共享程序的同乙個位址空間,分別完成相應的任務,並通過共享位址空間等方式完成執行緒間通訊,cpu按照時間片輪轉等方式對執行緒進行切換和排程。通常而言,執行緒共享的程序資源包括 linux中線程的建立依賴於lpthread.so 庫,建立乙個thr...

pthread建立多執行緒

include include include include include include include include include include include tinyxml tinyxml.h include include include include define macxm...

Linux 多執行緒 pthread

1.linux執行緒的發展 早在linux2.2核心中。並不存在真正意義上的執行緒,當時linux中常用的執行緒pthread實際上是通過程序來模擬的,也就是同過fork來建立 輕 程序,並且這種輕程序的執行緒也有個數的限制 最多只能有4096和此類執行緒同時執行。2.4核心消除了個數上的限制,並且...