1. 程式人生 > >15.執行緒:pthread_create;pthread_exit;pthread_join;pthread_detach;pthread_cancel;pthread_equal

15.執行緒:pthread_create;pthread_exit;pthread_join;pthread_detach;pthread_cancel;pthread_equal

注意: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);