最近想写一篇std::future的文章,先来总结下,线程的退出值,以及如何回收这个退出值。

这里主要参看了网上的文章,具体链接见文尾。

在Linux中,线程的应用还是比较广泛的,同时,线程退出的返回值对线程来说,也是一种比较客观的数据传输。

本文主要是在Linux中进行测试,不涉及windows等其他OS。

1. 线程的创建

    pthread_create(pthread_t *thread,const pthread_attr_t *attr,void*(*start_routine)(void*),void* arg);

首先,参数一:代表的是线程的pid地址

      参数二:代表的是是否设置线程的分离属性,这里设置为NULL,不分离

      参数三:代表的是线程的处理函数

      参数四:线程处理函数的参数列表,这里设置为NULL,不带参数内容

     (注意,这里主要是创建线程的作用)

2. 线程的等待

    pthread_join(pthread_t thread, void **retval)

首先:   参数一: 代表线程pid

          参数二: 代表线程的返回值 (--> 这个是本文讨论的重点参数)

3. 例子设计:

    这里设计两个线程,线程一是通过一般的return返回,作为线程的返回值;线程二,则是使用线程库中的pthread_exit()函数

来进行返回参数。

  首先,函数pthread_exit(void *retval)

       这里的retval就是线程退出的时候返回给主线程的值,也是今天需要讨论的情况。

  例子如下:

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#define PTHREAD_NUM    2

void *sendData(void *arg)
{
    static int count = 2;

    pthread_exit((void*)(&count));

}


void *recvData(void *arg)
{
    static int count = 3;

    return (void *)(&count);


}


int main(int argc,char *argv[])
{
    pthread_t pid[PTHREAD_NUM];
    int retPid;
    int *ret;
    int *dat;


    if((retPid = pthread_create(&pid[0],NULL,sendData,NULL)) != 0)
    {
        perror("create pid first failed");
        return -1;
    }


    if((retPid = pthread_create(&pid[1],NULL,recvData,NULL)) != 0)
    {
        perror("create pid second failed");
        return -1;
    }


    if(pid[0] != 0)
    {

        pthread_join(pid[0],(void**)&ret);
        printf("get thread 0 message: %d\n",*ret);
    }


    if(pid[1] != 0)
    {
        pthread_join(pid[1],(void**)&dat);
        printf("get thread 1 message: %d\n",*dat);
    }


    return 0;
}

讲解:这里的最主要的问题就是我们需要进行强制类型的转换。

  首先,对于pthread_exit这个函数,他的返回参数的类型为void *,现在我们返回的是一个“整数”,因此必须将其进行转换

       1. 先转换为整形指针,count为int类型,那么&count为int*类型,同样为了保持匹配,这里本人使用显式的调用,直接写作为

         &count,其实这个表明了现在变成了一个int的指针,这个时候与void*匹配的话,需要进行强制转换,也就是代码中的

         (void*)(&count);

       2. return这个关键字进行返回值得时候,同样也是需要进行强制类型的转换。线程函数的返回类型是void*,那么对于count这个

         整形数值来说,必须进行转换为void的指针类型(即void*),因此有:(void*)((int*)&count);

       3. 对于接收返回值的线程函数pthread_join来说,有两个作用。其一就是等待线程结束,其二就是获取线程结束的时候返回的数值

         是什么。所以,对于它的参数类型是void**这种二级指针的,我们可以把它分解为一级指针,这样就比较容易进行理解和调用。本文

        讨论的是整数,那么设置接收返回值得为一个整形指针,这样就感觉给二级指针void**降阶了。

       4. 对接收返回值得参数进行强制转换,这里定义接收返回值得类型是int*,因此转化为void**,也就是(void**)&ret,因为&ret就已

         经说明了现在的类型为int**,然后显式地转为void**即可

   5. 另外,本文在返回整数数值的时候使用到了static这个关键字,这是因为必须确定返回值的地址是不变的。对于count变量而言,在

         内存上来讲,属于在栈区开辟的变量,那么在调用结束的时候,必然是释放内存空间的,相对而言,这时候,就没办法找到count所代表

         内容的地址空间。这就是为什么很多人在看到swap交换函数的时候,为什么写成swap(int,int)是没有办法进行交换的,所以,如果我

         们需要修改传过来的参数的话,必须是要使用这个参数的地址,或者是一个变量本身是不变的内存地址空间,这样才可以进行修改,否则,

         修改失败或者返回值是随机值。

    结果:

python线程中有返回值 线程的返回值_linux

 

上述的结果表明,返回的数值是我们所要求的数值,是正确的。读者可以试着返回的是一个字符串,这样就比返回是一个整数

     更加简单明了。说到底,整篇文章也就是强制转换的结果。读者可以更加深入地自己去理解