一、執行緒的概念
執行緒是進程內部的一個基本執行流,是系統調度的一個實體。進程具有獨佔性,執行緒具有共享性。各執行緒共享程序的檔案描述符、訊號處理的方式、目前的工作目錄、使用者id(uid)和群組id(gid)。但有些資源執行緒是私有的,例如執行緒id、堆疊空間、上下文(包括各種暫存器的值。程式計數器和堆疊指標)、佔空間、訊號屏蔽字、調度優先權。就好比進程如果是一個家庭的話,線程就是這個家庭的成員,每個家庭的成員都有一個公共的空間(餐廳,客廳)。當然每個家庭成員也有自己的私人空間了。
二、執行緒的控制
創建執行緒和終止
用函數pthread_create()創建,成功回傳0,失敗返歸錯誤號碼。呼叫 pthread_create()建立新的執行緒後。當前執行緒從pthread_create()返回繼續往下執行。新的線程所執行的程式碼由函數指標start_routine決定。函數start_routine函數接收一個參數,是透過pthread_create()的arg傳給它的。類型為void*,start_toutine的回傳值型別也是void*,start_toutine回傳後,這個執行緒就退出了,其他執行緒可以呼叫pthread_join()得到start_toutine的回傳值。 start_toutine函數可以透過①return(void*)、②pthread_exit(void*)、③pthread_cancel(pthread_self())三種終止。
#include<stdio.h> 2 #include<pthread.h> 3 void * thread_run(void* arg) 4 { 5 int count=5; 6 while(1) 7 { 8 printf("this is a thread,thread id is\n"pthread_self()); 9 sleep(1); 10 } 11 //return (void*)1; 12 //pthread_exit((void*)2); 13 // pthread_cancel(pthread_self()); 14 } 15 int main() 16 { 17 pthread_t id; 18 int ret=pthread_create(&id,NULL,thread_run,NULL); 19 int count=10; 20 while(count-->0) 21 { 22 printf("this is a main thread,thread id is %u\n",pthread_self()); 23 sleep(1); 24 } 25 void * ted=0; 26 pthread_cancel(id); 27 pthread_join(id,&ted); 28 printf("return success %d\n",(int)ted); 29 }
可以看出:
1、如果透過return返回。 pthread_join接收的值是執行緒的回傳值
2、如果執行緒被別的執行緒呼叫pthread_cancel異常終止掉。則回傳錯誤碼
3、如果是呼叫pthread_exit終止的。 pthread_join存放的是傳給pthread_exit的參數。
4、兩個執行緒的執行緒號碼是不一樣的
三、執行緒分離
執行緒在任一個時間點。是可結合的(joinable)或是可分離的(detached)。可結合的線程可被其他的線程回收資源和殺死。在被其他執行緒回收之前,它的記憶體資源是不釋放的。而可分離的執行緒是不能被其他回收或殺死的,它的記憶體資源在它終止時由系統自動釋放。預設情況下。線程被創建成可結合的。為了避免記憶體洩漏,每個可結合的執行緒都應該要么被顯示的回收,即調用pthread_join;要么通過pthread_detach函數分離。
如果如果一個可結合線程結束運行但沒有被pthread_join,則它的狀態類似於進程中的殭屍進程,即還有一部分資源沒有被回收,所以創建線程者應該調用pthread_join來等待線程運行結束,並可得到執行緒的退出程式碼,回收其資源。呼叫pthread_join後,如果該執行緒沒有運行結束,呼叫者會被阻塞。這是可以在子執行緒中加入程式碼pthread_detach(pthread_self())或父執行緒呼叫pthread_detach(thread_id)非阻塞,可立即傳回。這將該子執行緒的狀態設為分離的(detached),如此一來,該執行緒運行結束後會自動釋放所有資源。
1 #include<stdio.h> 2 #include<pthread.h> 3 void* thread_run(void* arg) 4 { 5 pthread_detach(pthread_self()); //分离线程 6 printf("this is a thrad \n"); 7 return (void*)1; 8 } 9 int main() 10 { 11 pthread_t id; 12 int ret= pthread_create(&id,NULL,thread_run,NULL); 13 printf("this is a main thread\n"); 14 sleep(1); 15 16 int res=pthread_join(id,NULL); 17 if(res==0) 18 { 19 printf("pthrad wait succced\n"); 20 return 0; 21 } 22 else 23 { 24 printf("pthread wait faile\n"); 25 return 1; 26 } 27 return 0; 28 }
如果把子執行緒中的pthread_detach(pthread_self())註解掉,則結果如下,這是因為把子執行緒中分開去掉後,其他執行緒就可以對子執行緒進程join和殺死,然後釋放掉記憶體資源。而上面是因為在子進程中已經分離的,所以其他線程不能在對其訪問了,join返回fail
總結:
線程的控制從創建線程-->子線程的三種終止方式- ->其他線程join線程。終止的方式不同,join的回傳值就不同。線程的分離,如果子線程中加入pthread_detach()就把子線程設定成了可分離的線程,線程退出後會自動釋放記憶體資源,不會造成記憶體洩漏。如果不設定的話,就要用join顯示接收,然後釋放資源,也不會造成記憶體洩漏。
以上是Linux--線程的控制與分離的內容,更多相關內容請關注PHP中文網(www.php.cn)!