• pthread_join/pthread_exit的用法解析


    官方说法:

    函数pthread_join用来等待一个线程的结束。函数原型为:

      extern int pthread_join __P ((pthread_t __th, void **__thread_return));

      第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。这个函数是一个线程阻塞的函数,调用它的线程将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。一个线程的结束有两种途径,一种是象我们上面的例子一样,函数结束了,调用它的线程也就结束了;

    另一种方式是通过函数pthread_exit来实现。它的函数原型为:

      extern void pthread_exit __P ((void *__retval)) __attribute__ ((__noreturn__));

      唯一的参数是函数的返回代码,只要pthread_exit中的参数retval不是NULL,这个值将被传递给 thread_return。最后要说明的是,一个线程不能被多个线程等待,否则第一个接收到信号的线程成功返回,其余调用pthread_join的线程则返回错误代码ESRCH。

    上面说的有点乱,看不懂的看这里:

    pthread_join用于等待一个线程的结束,也就是主线程中要是加了这段代码,就会在加代码的位置卡主,直到这个线程执行完毕才往下走。

    pthread_exit用于强制退出一个线程(非执行完毕退出),一般用于线程内部。

    结合用法:

    一般都是pthread_exit在线程内退出,然后返回一个值。这个时候就跳到主线程的pthread_join了(因为一直在等你结束),这个返回值会直接送到pthread_join,实现了主与分线程的通信。

    注意事项:

    这个线程退出的返回值的格式是void*,无论是什么格式都要强转成void*才能返回出来主线程(pthread_exit((void*)tmp);),而这个时候pthread_join就去接这个值,我们传进去一个void*的地址也就是&(void*),传地址进去接值是接口类函数常用的做法,有同样效果的做法是引用&,但是这个做法一来值容易被误改,二来不规范,所以定义一个类型然后把地址传进去修改value。回到题目,这里返回的void*是一个指针类型,必须强转成对应的指针才能用。

    举个例子,如果是char* = “mimida”;传出来的tmp,必须(char*)tmp一下。

    而如果是int* a = new(3888);这种类型返回的tmp,必须*(int*)tmp一下才能用。

    最重要的一点,你定义的类型和最后出来的类型一定要一致,不然很容易出现问题。也就是你定义了int*,最后强转出来的一定是*(int*)。

    别void* a = (void*)10;这种诡异的格式(我就中过招),一开始是什么就转成什么!(这个规则同时也适用于线程数据里的set和get)

    实例如下:

    [cpp] view plain copy
    1.                        <pre name="code" class="cpp">/* example.c*/  
    2.   
    3. #include <stdio.h>  
    4.   
    5. #include <pthread.h>  
    6.   
    7. void thread1(char s[])  
    8. {   
    9.         printf("This is a pthread1. ");  
    10.         printf("%s ",s);  
    11.         pthread_exit((void*)"the first return!");  //结束线程,返回一个值。  
    12. }  
    13. void thread2(char s[])  
    14. {  
    15.         int *a = new(46666);  
    16. <span style="white-space:pre">    </span>printf("This is a pthread2. ");  
    17.         printf("%s ",s);  
    18.         pthread_exit((void*)a);  
    19. }  
    20.   
    21. /**************main function ****************/  
    22.   
    23. int main(void)  
    24.   
    25.   
    26. {  
    27.         pthread_t id1,id2;  
    28.         void *a1,*a2;  
    29.         int i,ret1,ret2;  
    30.         char s1[]="This is first thread!";  
    31.         char s2[]="This is second thread!";  
    32.         ret1=pthread_create(&id1,NULL,(void *) thread1,s1);  
    33.   
    34.         ret2=pthread_create(&id2,NULL,(void *) thread2,s2);  
    35.   
    36.         if(ret1!=0){  
    37.                 printf ("Create pthread1 error! ");  
    38.                 exit (1);  
    39.         }  
    40.         pthread_join(id1,&a1);  
    41.   
    42.         printf("%s ",(char*)a1);  
    43.   
    44.         if(ret2!=0){  
    45.                 printf ("Create pthread2 error! ");  
    46.                 exit (1);  
    47.         }  
    48.         printf("This is the  main process. ");  
    49.         pthread_join(id2,&a2);  
    50.         printf("%s ",*(int*)a2);  
    51.         return (0);  
    52.   
    53. }    
    
    


    运行结果: 
    [****@XD**** c]$ ./example 
    This is a pthread1. 
    This is first thread! 

    the first return!
    This is the main process. 
    This is a pthread2. 
    This is second thread! 

    46666

    http://blog.csdn.net/modiziri/article/details/41961595

  • 相关阅读:
    Vue--Vue-CLI服务命令、项目结构、自定义配置
    Vue--Vue-CLI创建项目
    Git
    前后端vue和django配置
    Django REST framework(DRF)
    Vue各种配置
    Vue组件
    vue项目搭建
    VUE基础
    Django中间件详解
  • 原文地址:https://www.cnblogs.com/feng9exe/p/8340594.html
Copyright © 2020-2023  润新知