You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 16:54:00