父进程和子进程之间有一个命名管道,子进程是写入者,父进程是读取者。父级创建此命名管道如下: os.mknod(events_pipe_file, 0o600 | stat.S_IFIFO)
并将此 events_pipe_file 传递给子进程,告诉子进程在这个命名管道中写入事件。
家长打开这个管道并阅读以下内容: event_stream = io.FileIO(self._events_file, "r") 对于 event_stream 中的行: ....
一开始,一切都很顺利,大约2小时后,父进程无法从这个命名管道中读取任何内容。我检查了子进程日志,它仍在正常地在这个命名管道中写入事件,直到完成其工作,然后子进程想要退出,但父进程陷入读取状态,然后,这个子进程就变成了僵尸。
我不明白,可能是什么原因导致父进程陷入从命名管道读取的困境?我不知道如何调试这个问题?
期望父进程正常读取,当子进程完成工作并退出时,父进程正常退出。
我认为父母被卡住可能是一些内存限制,因为我需要在内存中保存一些数据。
$ ulimit -a
核心文件大小(块,-c)0
数据段大小(kbytes,-d)无限制
调度优先级(-e)0
文件大小(块,-f)无限制
待处理信号 (-i) 255387
最大锁定内存(千字节,-l)64
最大内存大小(kbytes,-m)无限制
打开文件 (-n) 8192
管道大小(512 字节,-p)8
POSIX 消息队列(字节,-q)819200
实时优先级(-r)0
堆栈大小(千字节,-s)8192
CPU 时间(秒,-t)无限制
最大用户进程数 (-u) 255387
虚拟内存(千字节,-v)无限制
文件锁 (-x) 无限制
父进程:
$ pmap -x 464257|尾-f
00007f6d78532000 28 28 0 r--s-gconv-modules.cache
00007f6d78539000 8 8 8 rw--- [匿名]
00007f6d7853b000 4 4 4 r---- ld-2.28.so
00007f6d7853c000 8 8 8 rw---ld-2.28.so
00007ffe56d91000 136 84 84 rw---[堆栈]
00007ffe56de2000 16 0 0 r---- [匿名]
00007ffe56de6000 8 4 0 r-x-- [匿名]
ffffffffff600000 4 0 0 r-x-- [匿名]
---------------- ------- ------- -------
总KB 397260 65636 48660
对记忆没有意义。
问题已解决。
根本原因不在父子之间,命名管道也工作得很好。问题是父进程实际上也是一个子进程,它通过使用 subprocess.Popen() 由另一个进程启动。那么,实际上,我们有祖父母、父母、孩子。在祖父母和父母之间,我们有一个管道来相互通信,父母在其中写入,祖父母从其中读取。该管道被填满,然后父管道在写入时被阻止,它也无法从该命名管道读取消息。