使用fork()的C语言代码在ejudge平台出现Runtime Error的原因是什么?
代码触发Runtime Error的原因分析
1. 子进程逻辑错误导致进程数指数级暴涨
你的代码中,子进程成功通过scanf读取到单词后执行的是continue,会回到循环开头再次调用fork(),相当于每个成功读取单词的子进程都会继续创建新的子进程,进程数会指数级增长,很快超出ejudge平台的进程数限制,被系统强制杀死触发Runtime Error。本地测试时如果输入单词较少,可能刚好没触发进程数限制所以没有复现问题。
根据任务要求,每个进程最多读取1个单词,所以子进程读取到单词后应该直接以指定退出码退出,不应该继续循环创建进程。
2. 变量未初始化导致逻辑完全失控
你的循环从i=0开始执行,第一次fork操作发生在i=0阶段,但你只在i==1时才给first_child变量赋值,所以first_child初始是栈上的随机垃圾值,后续wait(&status) == first_child的判断逻辑完全不可控,会导致父进程随机提前退出、执行逻辑错乱。
3. 标准输入缓冲导致读取结果错乱
C标准库的stdin默认存在用户态缓冲区,fork()时会将父进程的缓冲区完整复制给所有子进程,导致多个子进程读到重复的缓冲内容,完全无法正确按顺序读取单词。
4. 计数逻辑完全不符合要求
你当前通过进程退出码传递计数的逻辑完全混乱,父进程没有正确累计所有成功读取单词的子进程数量,也无法正确判断所有子进程执行结束的时机。
修复后的参考代码
#include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include <unistd.h> int main() { // 关闭stdin用户态缓冲,避免多进程读重复内容 setvbuf(stdin, NULL, _IONBF, 0); int word_count = 0; pid_t child_pids[255]; int fork_cnt = 0; // 最多创建255个子进程对应最多255个单词 for (int i = 0; i < 255; i++) { pid_t pid = fork(); if (pid < 0) { exit(1); } else if (pid == 0) { // 子进程仅读取一次单词 char buf[4097]; if (scanf("%s", buf) != EOF) { // 读到单词则退出码为1 exit(1); } else { // 读到EOF则退出码为0 exit(0); } } else { child_pids[fork_cnt++] = pid; } } // 父进程等待所有子进程执行完毕,累计单词数 for (int i = 0; i < fork_cnt; i++) { int status; waitpid(child_pids[i], &status, 0); if (WIFEXITED(status)) { word_count += WEXITSTATUS(status); } } printf("%d\n", word_count); fflush(stdout); return 0; }
内容的提问来源于stack exchange,提问作者E1ZY
相关产品推荐
相关产品推荐

