fork(2)
我运行在Linux系统上的手册页说以下内容:为什么父进程的标准输入在关闭分叉子进程的标准输入文件描述符后仍然接受输入?
The child inherits copies of the parent's set of open file descriptors. Each file descriptor in the child refers to the same open file description (see open(2)) as the corresponding file descriptor in the parent. This means that the two file descriptors share open file status flags, file offset, and signal-driven I/O attributes (see the description of F_SETOWN and F_SET‐SIG in fcntl(2)).
和Python文档中提到
_exit()
should normally only be used in the child process after afork()
.
当然,_exit
不会调用清理处理程序,问题是, ,如果你看这个代码,例如:
newpid = os.fork()
if newpid == 0:
os.close(0)
else:
time.sleep(.25)
input()
父进程仍然接受输入尽管事实上子进程关闭了标准输入,但来自stdin。那好,下面的代码逆转:
newpid = os.fork()
if newpid == 0:
input()
else:
time.sleep(.25)
os.close(0)
现在,它的对面,这个时候,关闭标准输入不是孩子的父进程。这在子进程中调用input()
调用EOFError
。
这看起来像[child]进程写入/修改父级的文件描述符时,它不会影响[parent]。也就是说,子进程获取较新的文件描述。
那么为什么打电话_exit
作为Python文档状态来防止调用清理处理程序,如果由子进程执行的操作不影响父进程?让我们来看看_EXIT(2)
手册页:
The function
_exit() terminates the calling process "immediately". Any open file descriptors belonging to the process are closed; any children of the process are inherited by process 1, init, and the process's parent is sent a
SIGCHLD` signal.The function
_exit()
is likeexit(3)
, but does not call any functions registered with atexit(3) or on_exit(3). Open stdio(3) streams are not flushed. On the other hand,_exit()
does close open file descriptors, and this may cause an unknown delay, waiting for pending output to finish.
fork()
手册中没有提到的是,子进程的清理处理继承自父。这对父母有什么影响?换句话说,为什么不让孩子过程自己清理,为什么不呢?
'EOFError'不是由'os.close(0)'造成的。即使你使用'time.sleep(5)',你也可以立即得到它。 – Barmar
如果stdin被重定向到管道或文件,它也不会发生。 – Barmar