使用fork()时如何将pid值存入数据结构且后续可正常访问?
问题根源
你目前的问题核心是存储了栈变量的临时地址:pid是execCommand函数内的栈上局部变量,函数执行结束后这块内存会被后续函数调用复用覆盖,所有存储的指针最终都指向同一块被反复改写的内存,自然无法拿到正确的pid值。
修复方案
方案1:堆分配存储pid值(推荐,可移植性高)
直接在堆上申请独立内存存储pid的数值,避免栈变量被覆盖的问题。
1. 修改pid存入逻辑
将execCommand中后台进程的存储代码替换为:
else if (fg==0 && pid > 0) { // 申请堆内存存储pid值 int *pid_ptr = malloc(sizeof(int)); if (pid_ptr == NULL) { ERROR("pid storage malloc failed"); } *pid_ptr = pid; dll_put(running_processes, (Data)pid_ptr); attemptWait(); }
2. 补充内存释放逻辑
修改attemptWait函数,进程退出后记得释放对应的堆内存,避免内存泄漏。同时修复你代码中j变量同时承担返回值和状态存储的bug:
void attemptWait() { int wstatus; for(int i=0;i<dll_len(running_processes);i++) { int *pid_ptr = (int *)dll_ith(running_processes, i); int cur_pid = *pid_ptr; int ret = waitpid(cur_pid, &wstatus, WNOHANG); printf("child pid: %d\n", cur_pid); if(ret == cur_pid) { printf("[%d]+ Done\n", i); // 先从DLL中移除对应节点,再释放堆内存 dll_remove(running_processes, i); free(pid_ptr); i--; // 移除节点后下标回退,避免漏遍历 } else if (ret == -1) { printf("there was an error closing the %d-th process, pid: %d\n", i, cur_pid); } } }
方案2:直接转值存储(轻量,依赖平台兼容性)
如果你的运行平台支持int类型到void*的无损转换(大部分64位/32位系统都满足),可以不用申请堆内存,直接把pid的数值强转成void*存储:
1. 存入逻辑
dll_put(running_processes, (Data)(intptr_t)pid);
2. 读取逻辑
int cur_pid = (int)(intptr_t)dll_ith(running_processes, i);
这个方案不需要管理内存,但要注意必须引入<stdint.h>头文件使用intptr_t做中间转换,保证类型转换的安全性。
内容的提问来源于stack exchange,提问作者backward forward
相关产品推荐
相关产品推荐

