关于单pthread_t变量创建多线程的疑问:为何能并发执行?
pthread_t变量与多线程创建的误区解析
你的核心误解是把pthread_t变量和线程本身绑定了——实际上pthread_t只是一个用来存储线程标识符的变量,它的作用仅仅是记录某个线程的ID,和"只能创建一个线程"没有任何绑定关系。每次调用pthread_create时,只要传入它的地址,就会将新创建线程的ID写入这个变量,覆盖之前存储的值。
你的代码执行逻辑
你用全局pthread_t thread变量的写法,本质上是每次创建新线程时都把新线程的ID覆盖到这个全局变量里:
- main函数创建func1线程,
thread存储func1的线程ID - func1创建func2线程,
thread被覆盖为func2的线程ID - func2创建func3线程,
thread再次被覆盖为func3的线程ID - func3创建func4线程,
thread最终被覆盖为func4的线程ID
而每个线程中的pthread_join(thread, NULL)实际上都能正确等待对应的子线程:
- func1里的
pthread_join等待的是func2线程(因为func1调用pthread_create后,thread已经被更新为func2的ID) - func2里的
pthread_join等待func3线程 - func3里的
pthread_join等待func4线程 - main里的
pthread_join等待func1线程
这种嵌套创建+等待的结构,让所有线程的打印循环可以并发执行,所以你的代码能跑通,但写法存在风险。
潜在的线程安全问题
你的写法依赖线程执行的顺序:必须保证pthread_create写入thread后,对应的pthread_join才会读取它。如果代码逻辑更复杂,比如多个线程同时读写这个全局thread变量,就会出现读取到错误线程ID的情况,导致pthread_join等待错误的线程,甚至程序崩溃。
推荐的正确写法
为每个线程分配独立的pthread_t变量,避免ID被覆盖,逻辑更清晰也更安全:
#include <stdio.h> #include <unistd.h> #include <pthread.h> void *func4(void *arg) { for(int i = 0; i < 5; i++){ printf("/\n"); sleep(1); } return NULL; } void *func3(void *arg) { pthread_t tid4; // 独立变量存储子线程ID pthread_create(&tid4, NULL, func4, NULL); for(int i = 0; i < 5; i++){ printf("*\n"); sleep(1); } pthread_join(tid4, NULL); return NULL; } void *func2(void *arg) { pthread_t tid3; pthread_create(&tid3, NULL, func3, NULL); for(int i = 0; i < 5; i++){ printf("-\n"); sleep(1); } pthread_join(tid3, NULL); return NULL; } void *func1(void *arg) { pthread_t tid2; pthread_create(&tid2, NULL, func2, NULL); for(int i = 0; i < 5; i++){ printf("+\n"); sleep(1); } pthread_join(tid2, NULL); return NULL; } int main() { pthread_t tid1; pthread_create(&tid1, NULL, func1, NULL); pthread_join(tid1, NULL); return 0; }
内容的提问来源于stack exchange,提问作者Mehmet Ali K.
相关产品推荐
相关产品推荐

