为什么父进程的stdin在关闭派生子进程的stdin文件描述符之后仍然接受输入?

2024-03-28 19:58:04 发布

您现在位置:Python中文网/ 问答频道 /正文

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 a fork().

当然,_exit不会调用清理处理程序,问题是,如果您查看以下代码:

newpid = os.fork()
if newpid == 0:
    os.close(0)
else:
    time.sleep(.25)
    input()

父进程仍然接受来自stdin的输入,尽管子进程关闭了stdin。很好,代码颠倒过来了:

newpid = os.fork()
if newpid == 0:
    input()
else:
    time.sleep(.25)
    os.close(0)

现在,情况正好相反,这次是关闭stdin的父进程,而不是子进程。这将为子进程中的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 aSIGCHLD` signal.

The function _exit() is like exit(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()手册页没有提到子进程的清理处理程序是从父进程继承的。这对父母有什么影响?换言之,为什么不让子进程自己清理,为什么不呢?你知道吗


Tags: andoftheinchild进程osexit
1条回答
网友
1楼 · 发布于 2024-03-28 19:58:04

我假设你是在终端里的一个外壳上运行这个。你知道吗

shell在新的进程组中启动Python进程,并使用tcsetpgrp()将其设置为TTY上的前台进程组。你知道吗

一旦父Python进程终止,shell将收回对终端的控制权(它将自己设置为前台进程组)。shell不知道Python中的分叉子级仍在运行。你知道吗

当不属于前台进程组的进程尝试从终端读取数据时,它通常会收到SIGTTIN信号。但是,在本例中,进程组已被孤立,因为它的前导已终止,因此子进程从TTY上的read()获得一个EIO错误。Python将其视为EOFError。你知道吗

相关问题 更多 >