zoukankan      html  css  js  c++  java
  • Linux如何返回线程退出时的数据(以整数为例)

    在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就是线程退出的时候返回给主线程的值,也是今天需要讨论的情况。

      例子如下:

     1 #include <pthread.h>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <unistd.h>
     5 #include <errno.h>
     6 
     7 #define PTHREAD_NUM    2
     8 
     9 void *sendData(void *arg)
    10 {
    11     static int count = 2;
    12 
    13     pthread_exit((void*)(&count));
    14 
    15 }
    16 
    17 
    18 void *recvData(void *arg)
    19 {
    20     static int count = 3;
    21     
    22     return (void *)(&count);
    23 
    24 
    25 }
    26 
    27 
    28 int main(int argc,char *argv[])
    29 {
    30     pthread_t pid[PTHREAD_NUM];
    31     int retPid;
    32     int *ret;
    33     int *dat;
    34 
    35 
    36     if((retPid = pthread_create(&pid[0],NULL,sendData,NULL)) != 0)
    37     {
    38         perror("create pid first failed");
    39         return -1;
    40     }
    41 
    42     
    43     if((retPid = pthread_create(&pid[1],NULL,recvData,NULL)) != 0)
    44     {
    45         perror("create pid second failed");
    46         return -1;
    47     }
    48 
    49 
    50     if(pid[0] != 0)
    51     {
    52 
    53         pthread_join(pid[0],(void**)&ret);
    54         printf("get thread 0 message: %d
    ",*ret);
    55     }
    56 
    57 
    58     if(pid[1] != 0)
    59     {
    60         pthread_join(pid[1],(void**)&dat);
    61         printf("get thread 1 message: %d
    ",*dat);
    62     }
    63 
    64 
    65     return 0;
    66 }

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

      首先,对于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)是没有办法进行交换的,所以,如果我

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

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

        结果:

                  

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

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

  • 相关阅读:
    Oracle 服务命名(别名)的配置及原理,plsql连接用
    AdHoc发布时出现重复Provisioning Profile的解决方案
    xcode5时代如何设置Architectures和Valid Architectures
    C# WinForm 导出导入Excel/Doc 完整实例教程[使用Aspose.Cells.dll]
    DataTable的数据批量写入数据库
    高中生活--第7篇–我为什么不交作业
    ITFriend网站内测公测感悟
    网站推广第一周总结和反思
    第一次当面试官
    技术人才的出路在哪里,5种选择和2种思路
  • 原文地址:https://www.cnblogs.com/Older-Driver-of-Newer/p/6739316.html
Copyright © 2011-2022 走看看