C语言fork子进程调用函数时scanf被跳过致无限循环问题
问题根因
- 第一个fork创建的服务端子进程分支代码为空,执行完空分支后会直接退出。父进程仅调用了一次
wait,捕获到服务端子进程的退出信号后也会立刻结束,导致客户端子进程成为孤儿进程,失去控制终端的访问权限,读取标准输入时直接返回EOF。 - 代码未判断
scanf的返回值,当scanf读取失败(返回EOF)时不会修改input变量的值,input始终为初始值'a',既不满足退出循环的'q'条件,还会持续触发无效输入分支,最终形成无限循环。
修复方案
1. 修复main函数逻辑
- 给服务端子进程分支补充逻辑,或临时添加
exit(0)避免无意义退出 - 修改父进程等待逻辑,等待所有子进程退出后再结束
int main() { if ((serverChild = fork()) == 0) { // 此处补充服务端逻辑,临时调试可先加exit(0) exit(0); } else if ((clientChild = fork()) == 0) { SP_Pipe_Client(); exit(0); } else { // 循环等待所有子进程退出 while (wait(NULL) > 0); } return 0; }
2. 增加输入异常判断
在SP_Pipe_Client函数中,每次调用scanf后判断返回值,遇到读取失败/EOF时直接退出循环:
printf("Menu: [p]rint, [m]ove, [n]ew, [s]ave, [l]oad, [q]uit?\n"); int ret = scanf(" %c", &input); // 读取失败或读到EOF直接退出 if (ret <= 0) { break; }
内容的提问来源于stack exchange,提问作者Ashton Harris
相关产品推荐
相关产品推荐

