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

看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\n", 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("*\n");
pthread_join(tid, &result);
printf("ret:%s\n", (char *)result);

return 0;
}

对线程等待函数pthread_join二级指针参数分析的更多相关文章

  1. C++ 有关指针作为函数参数的问题,自定义内存分配函数传递二级指针的问题

    如题所示,我们主要讨论在自定义的内存分配函数中通常见到的代码如下所示: void Create(A** addr); 其中传递的参数是二级指针.为什么? 我们先看一下完整的动态内存分配函数的简单例子: ...

  2. WPF 自定义快速实现线程等待函数FastTask

    在WPF实现 我们常常需要实现这个目标:线程里面执行复杂的任务,然后主窗体等待动画 我把我最简单的东西给包了一下,更方便使用,大家也可以方便使用 1:添加CommHelper类 FastTask方法 ...

  3. C语言深度剖析-----数组参数和指针参数分析

    数组退化的意义 当向函数传递数组时, 二维数组参数 等价关系 注意事项 只能去一维数组 无法向一个函数传递一个任意的多维数组,注释地方出错 传递与访问二维数组的方式 动态地算出二维数组的列

  4. C语言的本质(16)——函数接口的传入参数与传出参数

    如果函数接口有指针参数,既可以把指针所指向的数据传给函数使用(称为传入参数),也可以由函数填充指针所指的内存空间,传回给调用者使用(称为传出参数),例如strcpy的函数原型为 char *strcp ...

  5. C++二级指针和指针引用传参

    前提 一级指针和引用 已经清晰一级指针和引用. 可参考:指针和引用与及指针常量和常量指针 或查阅其他资料. 一级指针和二级指针 个人觉得文字描述比较难读懂,直接看代码运行结果分析好些,如果想看文字分析 ...

  6. 【C】二级指针探秘 & 星号的两种用法(1.与基本类型结合形成另一种类型,比如与int结合形成int* 2.取值操作)

    1)问题:二级指针到底是什么?怎么用的?怎么存放的? #include <stdio.h> #define TEST_ADDR 0x12FF40 void main() { int a = ...

  7. C#中调用C++的dll的参数为指针类型的导出函数(包括二级指针的情况)

    严格来说这篇文章算不上C++范围的,不过还是挂了点边,还是在自己的blog中记录一下吧. C++中使用指针是家常便饭了,也非常的好用,这也是我之所以喜欢C++的原因之一.但是在C#中就强调托管的概念了 ...

  8. C-指针,二级指针,二维数组作为函数参数使用,C语言链表(详解)

    一级指针 int *p;            //表示定义一个int型(4字节)的指针p &p                 //表示p自身的地址位置 p                  ...

  9. FreeRTOS信号量的封装函数参数是二级指针

    1. 先看正确的封装方式,问题所在,为什么要用2级指针 void cissys_lockcreate(void** mutex) { //创建信号量,应该是互斥锁 *mutex = ((Semapho ...

随机推荐

  1. linux后台查看共享内存和消息队列的命令

    ipcs ipcs -q : 显示所有的消息队列 ipcs -qt : 显示消息队列的创建时间,发送和接收最后一条消息的时间 ipcs -qp: 显示往消息队列中放消息和从消息队列中取消息的进程ID ...

  2. DevExpress XtraPivotGrid 交叉表 重复显示问题

    转自:http://www.cnblogs.com/xiayan/archive/2011/11/04/2236389.html 最近发现xtrareport 的PivotGrid实现交叉表非常的简单 ...

  3. [CC]DgmOctree—执行Cell遍历和单元计算

    DgmOctree类的executeFunctionForAllCellsAtLevel和executeFunctionForAllCellsStartingAtLevel方法通过回调函数octree ...

  4. Python之路----------ConfigParser模块

    Python的ConfigParser 废话不说,拿去用 #coding=utf-8 import configparser ''' 基於Python3.0版本寫的配置文件的創建.增加.刪除.修改等方 ...

  5. 安装ionic出现node-sass无法下载的解决方法

    解决方法: 修改C:\users\[用户名]下的.npmrc文件: registry=https://registry.npm.taobao.org sass-binary-site=https:// ...

  6. echarts基础 handleIcon 设置

    1.自己引入echarts库 2.找到代码中dataZoom中的handleIcon ,看见对应的是"M0,0 v9.7h5 v-9.7h-5 Z",这是由svg画出来的图形,其中 ...

  7. iOS设置cell选中时文字颜色的变化

    cell.titleStr.highlightedTextColor = EMCGreenColor;

  8. python3爬取网页

    爬虫 python3爬取网页资源方式(1.最简单: import'http://www.baidu.com/'print2.通过request import'http://www.baidu.com' ...

  9. Web攻防之XSS,CSRF,SQL注入

    摘要:对Web服务器的攻击也可以说是形形色色.种类繁多,常见的有挂马.SQL注入.缓冲区溢出.嗅探.利用IIS等针对Webserver漏洞进行攻击.本文结合WEB TOP10漏洞中常见的SQL注入,跨 ...

  10. 用花生壳实现内网映射,决解无域名、无公网IP、无服务器空间问题

    无域名.无公网IP.无服务器空间用花生壳提供的免费内网映射吧.你的PC就是服务器,花生壳提供的自定义二级域名轻松访问你的个人网站. 1.首先你得注册哦,然后申请免费的域名(2个) 2.设置路由器,下面 ...