• 对线程等待函数pthread_join二级指针参数分析


    分析之前先搞明白,这个二级指针其实在函数内部是承接了上个线程的返回值。

    看man手册,发现返回值是个普通指针。人家用二级指针来承接,可能准备干大事。这个可以自己搜索一下。原因嘛,二级指针是保存了这个地址。一级指针承接的话就是这个地址。

    那既然二级指针保存了,我们如何访问那?开始我觉得直接来个二级指针,然后*访问算了,但是下面的东西。让你不能那么干了!其实非要那样也可以 malloc呗!

    线程创建函数pthread_create的函数原型如下:

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

    其中,thread是要创建的线程;

             attr指定线程的属性,缺省值为NULL;

              start_routine是线程要执行的函数;

              arg是传递给线程执行的函数的参数;

    要注意的是:start_routine是函数指针

    线程等待函数pthread_create的函数原型如下:

    int pthread_join(pthread_t thread, void **value_ptr);

    其中,thread是要等待的线程名;

             value_ptr:指针*value_ptr指向线程返回的参数

    在使用时要注意的是:针对value_ptr,应该先声明一个一级指针,然后通过取地址的方式传给pthread_create函数,而不应该直接定义一个二级指针,将这个二级指针直接传递给pthread_create。

    如:

    正确的传递方法:

    void *ret;

    pthread_join(thread, &ret);

    错误的传递方法:

    void **ret;

    pthread_join(thread, ret);

    原因:pthread_join中有一句类型这样的语句:(* value_ptr) = arg;如果按照正确的方式传递参数,左边的语句实际上完成的操作是:ret = arg;一点问题没有。但是,当按照错误的方式传递参数时,会出现一句致命的错误:(* value_ptr),它对一个还没有初始化的指针进行了取值操作,这是系统所不允许的,此时(* value_ptr)等价于*ret,*ret还是一个指针,是一个二级指针,但是*ret是一个野指针!

    注意啊!你返回的是一个一级指针,那么存储就只能是用 * &ret 来存储(希望你懂,就是指针降级)=ret;

    那么输出自然也就是 ret了。

    下面是一个例子:

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

    #define N 64

    int a = 10;
    void * handler(void *arg)
    {
    printf("a=%d, %s ", a, (char *)arg);
    strcat((char *)arg, " ......");
    pthread_exit(arg);
    }

    int main()
    {
    pthread_t tid;
    char buf[N] = {"welcome"};
    void *result;

    if (pthread_create(&tid, NULL, handler, (void *)buf) != 0)
    exit(-1);
    printf("* ");
    pthread_join(tid, &result);
    printf("ret:%s ", (char *)result);

    return 0;
    }

  • 相关阅读:
    js 图片压缩
    C#.NET中对称和非对称加密、解密方法汇总--亲测可用
    最精美详尽的 HTTPS 原理图
    swagger ui
    python爬取百度谷歌搜索结果
    Gitlab 11.0.3 迁移简明笔记
    ELK stack 7.6.x + kafka构建日志平台
    Nginx 内存占用高排查
    运维机器人 hubot 集成 jenkins
    运维机器人hubot,解放运维的神器
  • 原文地址:https://www.cnblogs.com/zhangfeionline/p/5975272.html
Copyright © 2020-2023  润新知