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);

猜你喜欢

转载自blog.csdn.net/weixin_36750623/article/details/83069230