这是 subprocess 库最容易被忽略的问题。
你现在已经开始考虑 O_CLOEXEC。
但建议系统化处理:
Unix
所有 fd 默认:
pipe2(O_CLOEXEC)
open(..., O_CLOEXEC)
fcntl(FD_CLOEXEC)
禁止:
pipe() + fcntl()
因为 fork 多线程 race。
Windows
必须严格控制:
SetHandleInformation(..., HANDLE_FLAG_INHERIT, 0)
以及:
STARTUPINFOEX
PROC_THREAD_ATTRIBUTE_HANDLE_LIST
否则会出现:
子进程意外继承 pipe,导致父进程永远读不到 EOF。
这是 Windows subprocess 最经典死锁之一。
这是 subprocess 库最容易被忽略的问题。
你现在已经开始考虑 O_CLOEXEC。
但建议系统化处理:
Unix
所有 fd 默认:
pipe2(O_CLOEXEC)
open(..., O_CLOEXEC)
fcntl(FD_CLOEXEC)
禁止:
pipe() + fcntl()
因为 fork 多线程 race。
Windows
必须严格控制:
SetHandleInformation(..., HANDLE_FLAG_INHERIT, 0)
以及:
STARTUPINFOEX
PROC_THREAD_ATTRIBUTE_HANDLE_LIST
否则会出现:
子进程意外继承 pipe,导致父进程永远读不到 EOF。
这是 Windows subprocess 最经典死锁之一。