我从execve的man页面读到,如果进程(A)调用execve,则已经打开的文件描述符被复制到新进程(B).
这里出现两种可能性: –
1)是否意味着为进程B创建了一个新的文件描述符表,从进程A的旧文件描述符表复制的条目
2)或者进程B获取进程A的文件描述符表,因为执行进程A将停止存在,并且已经打开的文件只能从进程B关闭,如果它获得进程A的文件描述符表.
哪一个是正确的?
解决方法
Which one is correct?
#2
虽然您要求的更多是操作系统实现细节,但对应用程序来说很少,但对应用程序完全透明,取决于操作系统.
通常说新进程继承了文件描述符.显然,除了设置了FD_CLOEXEC标志的那些.
即使在#1的情况下,如果我们假设在一段短时间内进程A和B都在内存中(不是真的,那就是fork()区域)复制fd表就可以了.由于进程A将被终止(通过exec()),它的所有文件描述符都将是close()d.这对过程B中已经复制的文件描述符没有影响.文件描述符就像指向相应内核结构的指针,包含有关文件描述符实际指向的实际信息.复制fd表不会复制底层结构 – 它只复制指针.内核结构包含引用计数器(实现fork()所需),它在复制时递增,因此知道有多少进程正在使用它.首先在文件描述符上调用close()会减少引用计数器.并且只有当计数器变为零(没有更多进程正在使用该结构)时,OS才会实际关闭底层文件/套接字/管道/等. (但显然即使内核内部有两个进程同时存在两个短时间,用户空间应用程序也看不到,因为exec()之后的新进程也继承了原始进程的PID.)