首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么父进程的stdin在关闭分叉子进程的stdin文件描述符后仍然接受输入?

问为什么父进程的stdin在关闭分叉子进程的stdin文件描述符后仍然接受输入?
EN

Stack Overflow用户
提问于 2017-07-06 13:13:21
回答 1查看 332关注 0票数 1

我正在运行的Linux系统上的fork(2)手册页面如下所示:

子节点继承父级打开的文件描述符集的副本。子文件描述符中的每个文件描述符与父文件描述符中的相应文件描述符引用相同的打开文件描述(参见open(2))。这意味着两个文件描述符共享打开的文件状态标志、文件偏移量和信号驱动的I/O属性(请参阅fcntl(2)中对F_SETOWN和F_SETOWN的描述)。

和Python文档提到

_exit()通常只应在fork()之后的子进程中使用。

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

代码语言:javascript
复制
newpid = os.fork()
if newpid == 0:
    os.close(0)
else:
    time.sleep(.25)
    input()

尽管子进程关闭stdin,父进程仍然接受来自stdin的输入。这很好,下面的代码是反向的:

代码语言:javascript
复制
newpid = os.fork()
if newpid == 0:
    input()
else:
    time.sleep(.25)
    os.close(0)

现在,正好相反,这一次关闭父进程的不是子进程。这将引发子进程中的EOFError调用input()。

这看起来就像子进程写入/修改父进程的文件描述符时,它不会影响父进程。也就是说,子进程获得较新的文件描述。

那么,如果子进程执行的操作不影响父进程,为什么调用_exit作为Python状态来阻止调用清理处理程序?让我们看一看_EXIT(2)手册页:

函数SIGCHLDsignal. 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()`关闭打开的文件描述符,这可能导致未知的延迟,等待挂起的输出完成。

fork()手册页面没有提到子进程的清理处理程序是从父进程继承的。这对父母有什么影响?换句话说,为什么不让孩子们自己清理一下,为什么不呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-06 13:40:35

我假设你是从终端的外壳中运行这个的。

shell在一个新的进程组中启动process,并使用tcsetpgrp()将其设置为TTY上的前台进程组。

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

当不属于前景进程组的进程试图从终端读取时,它通常接收SIGTTIN信号。但是,在这种情况下,进程组已经成为孤立的,因为它的领导终止了,因此子进程从TTY上的EIO从read()获得一个错误。Python将此视为EOFError。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44949988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档