execve()和共享文件描述符

Ash*_*ish 6 c operating-system

我从execve的手册页的阅读,如果一个进程(A)把execve,已经打开的文件描述符复制到新工艺(B).

这里出现两种可能性: -

1)是否意味着一个新的文件描述符表被用于处理B创建的,则条目被从过程A的较旧的文件描述符表复制

2)或进程B获得A处理文件描述符表作为execve的过程中A之后将不再存在,并且已经打开的文件只能从进程B关闭,如果它得到A处理的文件描述符表

哪一个是正确的?

R..*_*R.. 17

execve不会创建新流程.它根据文件系统中的可执行文件用新的替换调用进程的程序映像,内存空间等.通过使用close-on-exec标志设置关闭任何描述符来修改文件描述符表; 其余部分保持开放状态,处于相同状态之前(当前位置,锁定等)execve.

你可能与之发生在混淆这fork因为execve通常由前面fork.当进程分叉时,子进程有一个新的文件描述符表,引用与父进程的文件描述符表相同的打开文件描述.


Dum*_*001 7

哪一个是正确的?

#2

虽然您要求的更多是操作系统实现细节,但对应用程序来说很少,但对应用程序完全透明,取决于操作系统.

通常说新进程继承了文件描述符.显然,除了设置了FD_CLOEXEC标志的那些.

即使在#1的情况下,如果我们假设在一段短时间内进程A和B都在内存中(不是真的,那就是fork()区域)复制fd表就可以了.由于进程A将被终止(通过exec()),它的所有文件描述符都将是close()d.这对过程B中已经复制的文件描述符没有影响.文件描述符就像指向相应内核结构的指针,包含有关文件描述符实际指向的实际信息.复制fd表不会复制底层结构 - 它只复制指针.内核结构包含引用计数器(实现fork()所需),它在复制时递增,因此知道有多少进程正在使用它.首先在文件描述符上调用close()会减少引用计数器.并且只有当计数器变为零(没有更多进程正在使用该结构)时,OS才会实际关闭底层文件/套接字/管道/等.(但显然即使内核内部有两个进程同时存在两个短时间,用户空间应用程序也看不到,因为exec()之后的新进程也继承了原始进程的PID.)