1、線程的概念ide
線程是進程內部的一個基本執行流,是系統調度的一個實體。進程具備獨佔性,線程具備共享性。各線程共享進程的文件描述符、信號處理的方式、當前的工做目錄、用戶id(uid)和組id(gid)。可是有些資源線程是私有的,好比線程id、棧空間、上下文(包括各類寄存器的值。程序計數器和棧指針)、佔空間、信號屏蔽字、調度優先級。就比如進程若是是一個家庭的話,線程就是這個家庭的成員,每一個家庭的成員都有一個公共的空間(餐廳,客廳)。固然每一個家庭成員也有本身的私人空間了。
函數
2、線程的控制ui
建立線程和終止this
用函數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())三種終止。
spa
1 #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 }
一、若是經過return返回。pthread_join接收的值是線程的返回值
指針
二、若是線程被別的線程調用pthread_cancel異常終止掉。則返回錯誤碼
blog
三、若是是調用pthread_exit終止的。pthread_join存放的是傳給pthread_exit的參數。
進程
四、兩個線程的線程號是不同的
內存
3、線程分離
線程在任一個時間點上。是可結合的(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顯示接收,而後釋放資源,也不會形成內存泄漏。