关于pthread中void*转long的疑问:是否需先解引用?
嘿,这个问题问得特别到位!其实这里的核心是你的教授并没有把threadid当成「指向long的指针」来使用,而是用了一个在pthread编程里很常见的小技巧:把long值直接塞进了指针变量本身的存储空间里,而不是让指针指向一个真正的long变量。
咱们拆解来看:
首先,如果
threadid真的是指向long类型变量的指针,那你的想法完全正确——应该先把void*转成long*,再解引用拿到值,比如:long tid = *(long*)threadid;这是指针的常规用法:指针存储的是另一个变量的地址,解引用才能拿到地址对应的内容。
但教授的写法对应的是另一种场景:在创建线程时,我们需要给线程函数传递一个
void*类型的参数。如果要传递的是一个小整数(比如线程ID),很多开发者会直接把这个整数的值转换成void*传进去,而不是专门为这个整数分配内存。比如创建线程的代码可能是这样的:pthread_t thread; long thread_num = 5; // 直接把long值转成void*传给线程函数 pthread_create(&thread, NULL, your_thread_func, (void*)thread_num);这时候,线程函数里的
threadid变量存储的不是某个long变量的地址,而是那个long值本身(因为在大多数系统上,指针的字节宽度和long是一样的,比如64位系统都是8字节,所以可以安全地互相转换)。这时候直接把void*转成long就能拿到原始值,完全不需要解引用——因为它本来就不是一个有效的内存地址,就是个伪装成指针的整数。额外提一句:这种写法虽然常见,但有一定的可移植性风险。如果某个系统的指针宽度和long不一样,转换就会出问题。更规范的做法是用
<stdint.h>里的intptr_t或uintptr_t,这两个类型是专门设计用来和指针互相转换的整数类型,比如:// 传参时 pthread_create(&thread, NULL, your_thread_func, (void*)(intptr_t)thread_num); // 线程函数里取值 intptr_t tid = (intptr_t)threadid;
总结一下:你的想法在「指针指向long变量」的常规场景下是完全正确的,但教授这里是另一种特殊用法——把整数直接存在指针变量里,所以不需要解引用。
内容的提问来源于stack exchange,提问作者Qwerto




