为何pthread_join通过指针而非二级指针传递线程返回值?代码问题解析
问题现象回顾
你编写的线程代码预期能获取子线程返回的42,但通过(void**)&status_child_ptr传入pthread_join时,输出的status_child始终为0;去掉&传入(void**)status_child_ptr则能得到预期结果。
核心原因:pthread_join参数的作用逻辑
pthread_join的第二个参数是void**类型,它的核心作用是:将子线程返回的void*值,写入到该二级指针指向的内存地址中。
子线程的返回值本质是void*类型,你代码里的return 42会被隐式转换为void*(即把整数42当作一个内存地址处理)。
错误用法的本质
看你这段错误代码:
int status_child; int* status_child_ptr = &status_child; int status_joined = pthread_join(thread_id, (void**)&status_child_ptr);
&status_child_ptr是int**类型,强制转为void**后,pthread_join会把线程返回的(void*)42直接写入status_child_ptr这个指针变量本身的内存——也就是说,你修改的是status_child_ptr的值,让它变成了指向地址0x2A(42的十六进制)的指针,根本没碰status_child的内存,所以status_child保持初始值0。
正确用法的逻辑
当你去掉&写成(void**)status_child_ptr时,是把指向status_child的int*指针强制转为void**。此时pthread_join会把线程返回的(void*)42写入到这个指针指向的内存(也就是status_child的地址),相当于直接给status_child赋值42,所以能得到预期结果。
不过这种写法属于类型转换的“非标准用法”,更规范安全的写法是用void*接收返回值再转成int:
void* ret_val; int status_joined = pthread_join(thread_id, &ret_val); int status_child = (int)ret_val;
这完全符合pthread_join的参数定义,避免类型不匹配的潜在问题。
关于status_child的疑问
status_child就是普通的int变量,不是指针。你的困惑源于对pthread_join参数传递逻辑的误解——它不是直接给传入的指针赋值,而是通过二级指针修改目标变量的内存。
内容的提问来源于stack exchange,提问作者jka

