Linux下该C语言代码为何只输出0后挂起而非输出0到999?
问题原因分析
- 最根本的错误是代码中定义的指针
x为空指针,没有指向合法的可读写内存空间:
代码里int *x = 0;等价于将x初始化为NULL,而read、write系统调用的第二个参数要求是用户空间的有效缓冲区地址,传入空指针时系统调用会直接返回EFAULT错误,不会执行实际的管道读写操作。 - 该错误直接引发父子进程死锁:
父进程第一次循环打印0后,调用write(fromparent[1], x, 1)触发错误,没有任何数据写入管道,紧接着父进程就阻塞在read(fromchild[0], x, 1)调用上,等待子进程回传数据。
而子进程一直阻塞在read(fromparent[0], x, 1)调用上,永远等不到父进程写入的数据,自然也不会往fromchild管道写入任何数据,父子进程互相等待,程序就进入挂起状态不再继续执行。
修复方案
只需要把空指针改为合法的栈变量,传递变量地址作为读写缓冲区即可,示例修改如下:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { int n = 1000; int fromparent[2]; int fromchild[2]; char x; // 修改为普通char类型变量,不需要指针 pipe(fromparent); pipe(fromchild); if (fork() == 0) { /* child */ while (1) { read(fromparent[0], &x, 1); // 传变量地址作为缓冲区 write(fromchild[1], &x, 1); } } else { /* parent */ for (int i = 0; i < n; i++) { printf("%d\n", i); write(fromparent[1], &x, 1); read(fromchild[0], &x, 1); } exit(0); } }
内容的提问来源于stack exchange,提问作者andi
相关产品推荐
相关产品推荐

