15.執行緒:pthread_create;pthread_exit;pthread_join;pthread_detach;pthread_cancel;pthread_equal
阿新 • • 發佈:2018-11-12
注意:pthread的返回值
成功:幾乎全是返回0
失敗:返回非0
1.檢視執行緒ID
1.找到程式的程序ID:ps aux | grep 程式名
2.ps -Lf 程序ID:LWP
2.pthread_create
int pthread_create( pthread_t *thread, //傳出引數:執行緒ID=unsigned long const pthread_attr_t *attr, //執行緒屬性,NULL void *(*start_routine) (void *), //執行緒回撥函式 void *arg //執行緒回撥函式的引數 ); 返回值: 成功返回0,失敗返回錯誤號 perror()不能使用該函式列印錯誤資訊,而是使用strerror(ret),列印錯誤碼 注意:主執行緒先退出,子執行緒會被強制結束 程式案例* 重點:int和void*之間的強制轉換----->(直接強制轉換即可) void* myfunc(void* arg){ printf("%dth child thread id = %lu\n",(int)arg,pthread_self()); //printf("%dth child thread id = %lu\n",*(int*)arg,pthread_self()); for(int i=0;i<5;i++){ if(i==(int)arg) pthread_exit(NULL); //return NULL; } return NULL; } int main(){ pthread_t tid[5]; int i; for(i=0;i<5;i++){ int ret=pthread_create(&tid[i],NULL,myfunc,(void*)i); //pthread_create(&tid[i],NULL,myfunc,(void*)(&i)); if(ret!=0){ //pthread_create的返回值 printf("error number : %d\n",ret); //列印錯誤碼 printf("%s\n",strerror(ret)); //strerror(ret) } } printf("parent thread id = %lu\n",pthread_self()); sleep(1); }
3.pthread_exit
void pthread_exit(void *retval);
retval:當執行緒函式中,執行pthread_exit退出後,retval引數被主執行緒pthread_join函式
的第二個引數接收到。
4.pthread_join 阻塞等待執行緒退出,回收TCB,獲取執行緒退出狀態
int pthread_join(pthread_t thread, void **retval); 作用:使主執行緒等待執行緒ID=thread子執行緒執行完後,才退出;[獲取子執行緒的返回值] thread:要回收的子執行緒的執行緒ID retval:(傳出引數)讀取執行緒退出的時候攜帶的狀態資訊 void* ptr; pthread_join(tid,&ptr); 指向的記憶體和pthread_exit的引數指向同一塊記憶體地址
案例:pthread_exit和return:返回執行緒函式中的值
struct node{ int data; char buf[1024]; }; void* thread_func(void* arg){ struct node* nd=(struct node*)malloc(sizeof(struct node)); nd->data=100; strcpy(nd->buf,"Thunder"); //pthread_exit(nd); //方法1 return nd; //方法2 } int main(){ pthread_t tid; int ret=pthread_create(&tid,NULL,thread_func,NULL); if(ret!=0) printf("ret=%d,error=%s\n",ret,strerror(ret)); void* retval=NULL; pthread_join(tid,&retval); printf("%d,%s\n",((struct node*)retval)->data,((struct node*)retval)->buf); } 程式碼分析: 執行緒函式:pthread_exit(nd); return(nd); struct node* nd=(struct node*)malloc(sizeof(struct node)); nd->data=100; strcpy(nd->buf,"Thunder"); //pthread_exit(nd); //方法1 return nd; //方法2 主執行緒中:pthread_join獲取retval void* retval=NULL; pthread_join(tid,&retval); //retval指標指向nd printf("%d,%s\n",((struct node*)retval)->data,((struct node*)retval)->buf);
5.pthread_detach 執行緒分離
1.預設建立的執行緒,是不分離的,可能會產生殭屍執行緒,如何解決?
1.在主執行緒中呼叫pthread_join函式,等待子執行緒全部執行完畢後,主執行緒才退出
2.子執行緒中呼叫pthread_detach函式,使得子執行緒從主執行緒中分離,子執行緒的資源由系統回收
2.如何使執行緒分離?
[1]在子執行緒中呼叫pthread_detach函式
int pthread_detach(pthread_t thread);
[2]在建立執行緒之前,設定執行緒屬性為[分離]
pthread_attr_t attr; //執行緒屬性型別
int pthread_attr_init(pthread_attr_t *attr); //初始化
int pthread_attr_destroy(pthread_attr_t *attr); //釋放
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate); //[獲取]attr的分離狀態
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); //[設定]attr的分離狀態
attr:執行緒屬性
detachstate:
PTHREAD_CREATE_DETACHED (分離)
PTHREAD_CREATE_JOINABLE (不分離)
[案例]:
pthread_attr_t attr; //定義執行緒屬性變數
pthread_attr_init(&attr); //初始化執行緒屬性變數
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); //設定attr為執行緒可分離
pthread_create(&tid,&attr,pthread_func,NULL); //建立執行緒時,使用attr引數
pthread_attr_destroy(&attr); //最終不要忘記,釋放attr
6.pthread_cancel 殺死(取消)執行緒
int pthread_cancel(pthread_t thread);
1.作用:在主執行緒中,取消執行緒ID=thread的執行緒
2.注意事項:要殺死的子執行緒的執行緒處理函式內部,必須做過一次[系統呼叫]。換句話說,取消點必
須是[系統呼叫],如果被取消的執行緒沒有系統呼叫,則該執行緒不能被取消。
3.pthread_testcancel(); //設定一個取消點
如果執行緒的處理函式中確實沒有[系統函式],可以呼叫pthread_testcancel()函式設定一個取消點,使得
該子執行緒能夠被pthread_cancel函式取消。
7.pthread_equal 判斷兩個執行緒的ID是否相等
int pthread_equal(pthread_t t1, pthread_t t2);