C语言多进程管道通信问题:子进程与父进程数据传递异常排查
close()系统调用本身绝对不会修改用户态的内存数组,你看到的mem数组值在close(Pipe1[0])前后变化,本质是代码里藏着非法内存访问或管道描述符管理错误,close只是把问题暴露出来的触发点而已。
下面是几个最可能的原因:
内存越界访问
子进程2读取Pipe1数据时,如果read()调用传入的缓冲区长度大于mem数组的实际大小,写入的数据会超出数组边界,破坏栈上的其他数据(包括mem数组自身的后续元素,或者相邻变量)。这种越界不一定会立刻显现,直到执行close()时栈帧发生变动,被破坏的mem数组值才会被你观察到。管道描述符管理混乱
要是子进程2没正确关闭无关的管道描述符——比如创建了两个管道(Pipe1用于子1→子2,Pipe2用于子2→父),但子进程2没关Pipe1的写端(Pipe1[1])或Pipe2的读端(Pipe2[0])——会导致管道的EOF状态无法正常触发,子进程2的read()调用行为异常(比如阻塞或读到垃圾数据),间接引发内存操作错误。更糟的是,如果代码里把管道描述符和mem数组地址搞混(比如把描述符当指针用),执行close()时会直接操作非法内存地址,把mem数组搞坏。fork后的资源共享问题
fork()之后子进程会复制父进程的所有文件描述符和内存空间,如果父进程在fork()后没正确关闭不需要的管道描述符,会导致管道引用计数异常,影响子进程2的读写操作。比如父进程没关Pipe1的读端,子进程2读取Pipe1时收不到EOF,会持续读取垃圾数据覆盖mem数组。未初始化内存或栈溢出
如果mem数组没正确初始化,栈上的随机值会被当成有效数据,而close()操作可能触发栈帧调整,让未初始化的内存区域被覆盖,看起来像是close()修改了数组值。
内容的提问来源于stack exchange,提问作者fabrice

