c-为什么retval在pthread_join中是一个void**



我很难理解为什么pthread_joinretval参数是void**。我读过手册页,试着把它包起来,但我仍然无法完全理解。我无法说服自己retval不可能是void*。有人能启发我一下吗?

提前非常感谢!

这是因为您应该向pthread_join提供void*的地址。pthread_join将把pthread_exit(void*)提供的地址写入变量(您提供的地址)。

示例场景:

typedef struct {
// members
} input_data;
typedef struct {
// members
} output_data;

起始螺纹侧:

input_data id;
pthread_create(..., start_routine, &id);
void* start_routine(void *ptr) {
input_data *id = ptr;
output_data *od = malloc(sizeof *od);
// use the input data `id`, populate the output data `od`.
pthread_exit(od);
}

连接侧:

output_data *od;
pthread_join((void**) &od);
// use `od`
free(od);

足够简单。提供给pthread_create的线程func的返回值为void*pthread_join应该将这个值返回给调用者。

它不能将其作为函数返回类型返回(因为它已经返回int来指示调用的总体状态)。唯一的其他方式是through-out参数。

C输出参数的方法是使用指向参数实际类型的指针,也就是说,如果你想将int作为输出参数,那么参数的类型应该是int*。如果out参数是void*(因为这是从pthread func返回的!),那么参数的类型将变为void**

作为练习,您可以尝试自己编写类似的代码——首先,创建一个返回void*(比如void* foo())的函数,然后尝试编写另一个调用foo()并将结果反馈给调用者的函数。

退出的线程将提供一个指向某些数据的指针。pthread例程不知道数据的类型,所以它们接收作为void *的指针。

CCD_ 22的呼叫者将接收该CCD_ 23。由于函数返回值用于其他用途,因此必须通过参数接收void *。因此,调用者必须传递一个指向pthread_join将把void *放在哪里的指针。该指针是指向作为void **void *的指针。

来自手册页:

如果retval不为NULL,则pthread_join()将目标线程的退出状态(即目标线程提供给pthread_exit(3)的值)复制到retval指向的位置。

让我们看看pthread_exit的签名。

noreturn void pthread_exit(void *retval);

这意味着,如果我们想从线程返回int,它看起来像这样:

void* foo() {
// ...
int value = 255;
pthread_exit(&value);
}

这样做是因为编译器不在乎它是int*还是void*,无论哪种方式,它都是相同大小的指针。

现在,我们想要使用pthread_join实际提取线程的返回值。

void bar() {
pthread_t thread_id;
int *returnValue;
// create thread etc...
// the original type of returnValue was an `int*` so when we pass it in
// with "&" it's now become `int**`
pthread_join(thread_id, &returnValue);
printf("%dn", *returnValue); // should print 255
}

在普通英语中,pthread_join获取一个指针,并将其地址设置为指向线程中的retval。它是void**,因为我们需要指针的地址才能将底层指针设置为我们想要的。

相关内容

  • 没有找到相关文章

最新更新