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

Ubuntu下C语言进程编程问题:多进程随机数求和程序陷入死循环

解决多进程创建后无限循环的问题

看起来你遇到的核心问题是子进程没有跳出创建进程的循环,导致不断生成新的进程——当调用fork()时,子进程会完全复制父进程的地址空间(包括当前循环的计数器),然后从fork()的下一行代码开始执行。如果子进程不主动退出循环,它会继续迭代,不断创建新的子进程,最终引发无限循环。

下面是修正后的完整代码,我会标注关键的修复细节:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <time.h>
#include <errno.h>

int main(int argc, char *argv[]) {
    // 1. 校验命令行参数合法性
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <number_of_processes>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    int n = atoi(argv[1]);
    if (n <= 0) {
        fprintf(stderr, "Please enter a positive integer for n\n");
        exit(EXIT_FAILURE);
    }

    int total = 0;

    // 2. 循环创建n个进程
    for (int i = 0; i < n; i++) {
        pid_t pid = fork();

        if (pid == -1) {
            perror("fork failed");
            exit(EXIT_FAILURE);
        } else if (pid == 0) {
            // 子进程专属逻辑:生成随机数、打印后立即退出(关键!)
            // 用时间+进程ID设置唯一种子,避免所有子进程生成相同随机数
            srand(time(NULL) ^ getpid());
            int num = (rand() % 201) - 100; // 生成-100到100的随机数
            printf("Process %d (PID: %d) generated: %d\n", i+1, getpid(), num);
            
            // 偏移100后用退出状态传递数值(退出状态仅支持0-255无符号值)
            exit(num + 100);
        } else {
            // 父进程逻辑:等待子进程结束,收集计算结果
            int status;
            waitpid(pid, &status, 0);
            if (WIFEXITED(status)) {
                int num = WEXITSTATUS(status) - 100;
                total += num;
            } else {
                fprintf(stderr, "Process %d exited abnormally\n", pid);
            }
        }
    }

    printf("\nTotal sum of all random numbers: %d\n", total);
    return EXIT_SUCCESS;
}

关键修复点说明:

  • 子进程必须主动退出循环:在子进程分支中,完成随机数生成和打印后立即调用exit(),避免子进程继续执行父进程的循环逻辑,防止无限创建新进程。
  • 设置唯一的随机数种子:如果所有子进程都用time(NULL)作为种子,由于进程创建速度极快,多个子进程可能拿到相同的时间戳,导致生成完全相同的随机数。用time(NULL) ^ getpid()结合时间和进程ID,保证每个子进程的种子唯一。
  • 正确传递子进程结果:退出状态仅支持0-255的无符号值,因此我们把随机数偏移100(转为0-200的范围),父进程拿到结果后再减100还原原始值。如果后续需要处理更大范围的数值,建议改用管道或共享内存来传递数据。
  • 等待子进程结束:父进程用waitpid()逐个等待子进程完成,既可以按顺序收集结果,也能避免产生僵尸进程。

编译和运行方式:

gcc -o random_sum random_sum.c
./random_sum 5

运行后你会看到每个子进程打印自己生成的随机数,最后输出所有数的总和,不会再出现无限循环的问题。

内容的提问来源于stack exchange,提问作者Neil Shah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:05:05