pthread_create参数传递异常:线程获取值与预期不符问题咨询
问题原因
核心问题是线程访问了已被销毁的局部变量内存:createThreads函数里的pipeFd是栈上的局部变量,当pthread_create创建线程后,函数直接返回,栈上的pipeFd会被系统回收。而新线程可能在函数返回后才启动执行,此时访问&pipeFd指向的内存,拿到的是被覆盖后的无效垃圾值(这里恰好是0)。
另外补充:你的线程函数readFifo没有返回void*类型值,会触发未定义行为,建议补充return NULL;。
修复方案
以下三种方式都能解决问题,可根据业务场景选择:
方案一:使用全局变量
把pipeFd定义为全局变量,避免函数返回后内存被销毁:
#include <stdio.h> #include <pthread.h> #include <unistd.h> int pipeFd; // 全局变量 void *readFifo(void *pFd) { printf("get %d\n", *(int*)pFd); return NULL; } int createThreads(char *pipeName) { pipeFd = 3; printf("begin to pass %d\n", pipeFd); pthread_t tid; if(pthread_create(&tid, NULL, readFifo, &pipeFd) < 0) { printf("create thread failed\n"); return -1; } return 0; } int main(int argc, char*argv[]) { char *pipeName; pipeName = argv[1]; if(createThreads(pipeName) < 0) { printf("init read threads failed\n"); return -1; } while(1){ sleep(10000); } return 0; }
方案二:动态分配堆内存
用malloc在堆上分配参数内存,线程执行完后手动释放:
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h> void *readFifo(void *pFd) { int fd = *(int*)pFd; printf("get %d\n", fd); free(pFd); // 释放堆内存 return NULL; } int createThreads(char *pipeName) { int *pipeFd = malloc(sizeof(int)); if(pipeFd == NULL) { printf("malloc failed\n"); return -1; } *pipeFd = 3; printf("begin to pass %d\n", *pipeFd); pthread_t tid; if(pthread_create(&tid, NULL, readFifo, pipeFd) < 0) { printf("create thread failed\n"); free(pipeFd); // 创建失败也要释放内存 return -1; } return 0; } int main(int argc, char*argv[]) { char *pipeName; pipeName = argv[1]; if(createThreads(pipeName) < 0) { printf("init read threads failed\n"); return -1; } while(1){ sleep(10000); } return 0; }
方案三:等待线程执行完成再返回
如果业务允许,在createThreads中调用pthread_join等待线程执行完毕,确保局部变量在被使用期间不会销毁:
#include <stdio.h> #include <pthread.h> #include <unistd.h> void *readFifo(void *pFd) { printf("get %d\n", *(int*)pFd); return NULL; } int createThreads(char *pipeName) { int pipeFd = 3; printf("begin to pass %d\n", pipeFd); pthread_t tid; if(pthread_create(&tid, NULL, readFifo, &pipeFd) < 0) { printf("create thread failed\n"); return -1; } pthread_join(tid, NULL); // 等待线程执行完成 return 0; } int main(int argc, char*argv[]) { char *pipeName; pipeName = argv[1]; if(createThreads(pipeName) < 0) { printf("init read threads failed\n"); return -1; } while(1){ sleep(10000); } return 0; }
内容的提问来源于stack exchange,提问作者Klen
相关产品推荐
相关产品推荐

