对线程等待函数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\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;
}

时间: 2024-10-22 19:54:17

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

第35课 数组参数和指针参数分析

1. 数组参数退化为指针的意义 (1)C语言中只会以值拷贝的方式传递参数,当向函数传递数组时,将整个数组拷贝一份传入函数导致执行效率低下,C语言以高效作是最初的设计目标,所以这种方法是不可取的. (2)参数位于栈上,太大的数组拷贝将导致栈溢出. (3)将数组名看做常量指针,传递的是数组的首元素地址,而不是整个数组. 2. 二维数组参数 (1)二维数组参数同样存在退化的问题: 二维数组可以看做是一维数组,其中的每个元素又是一个一维数组 (2)二维数维参数中第一维的参数可以省略 ①void f(in

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

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

二级指针的使用详解

欢迎转载,转载请注明原文地址:http://blog.csdn.net/majianfei1023/article/details/46629065 一.概念 在如下的A指向B.B指向C的指向关系中: 首先 C是"一段内容",比如你用malloc或者new分配了一块内存,然后塞进去"一段内容",那就是C了.C的起始地址是0x00000008. B是一个指针变量,其中存放着C的地址,但是B也要占空间的啊,所以B也有地址,B的起始地址是0x00000004,但是B内存中

指针参数--指针做参数时应该注意的地方

转自:http://blog.csdn.net/sszgg2006/article/details/9037675 首先看以下程序: [cpp] view plain copy #include <stdio.h> int *swap(int *px, int *py){ int temp; temp = *px; *px = *py; *py = temp; return px; } int main(void){ int i = 10, j = 20; int *p = swap(&

C++二级指针和指针引用

前提 已经清晰一级指针和引用. 可参考:指针和引用与及指针常量和常量指针 或查阅其他资料. 一级指针和二级指针 例子 个人觉得文字描述比较难读懂,直接看代码运行结果分析好些,如果想看文字分析,可参考文末参考文章. #include <iostream> using namespace std; void make(int **pp) { **pp = 66;//这样只是改变了指向的值,即a, 指向没有改变 } int main() { int a=5; int *q=&a; int *

二级指针作为函数参数的典型用法

用二级指针作为函数参数,有两种典型情况:1.需要传递一级指针的数组时:例如标准C的main函数:int main(int argc, char*[] argv),数组最高维可以退化,char*[] argv等价于char** argv.这里argv代表命令行参数数组.2.需要对传入的一级指针进行修改时:例如:void alloc_new_char_array(int n, char** t){*t = (char*)malloc(n * sizeof(t));}这里可以通过返回值达到相同的效果,

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

严格来说这篇文章算不上C++范围的,不过还是挂了点边,还是在自己的blog中记录一下吧. C++中使用指针是家常便饭了,也非常的好用,这也是我之所以喜欢C++的原因之一.但是在C#中就强调托管的概念了,指针就不用想了.本来如果就在C#的世界里面写代码,也还算舒服,但是万事万物总有联系,这不,现在公司的另外一个用C#作的项目就碰到问题了,要调用之前用C++写的一个DLL中的一些函数,很多函数的参数都是指针类型的,这下可麻烦咯,公司里做C#的都是刚起步,C++又只有我最熟悉,这项技术研究工作又光荣的

函数参数是二级指针的问题

实际应用中再一次遇到了函数参数是二级指针的问题,如下是正确的版本 void main(void) { //一级指针 uint8 *value_data_string = NULL; fun_change(&value_data_string ); printf((char *)value_data_string ); fun_free(&value_data_string ); } void fun_change(uint8 **tem_buf) { int value_len = 5;

二级指针和函数参数——指针参数是如何传递内存的?

1:如果函数的参数是一个指针,不要指望用该指针去申请动态内存.Test 函数的语句 GetMemory(str, 200)并没有使 str 获得期望的内存,str 依旧是 NULL,为什么? void GetMemory(char *p, int num) { p = (char *)malloc(sizeof(char) * num); } void Test(void) { char *str = NULL; GetMemory(str, 100); // str 仍然为 NULL strc