Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我应该使用什么方法来知道哪些FD在进程分叉之后打开,然后是EXEC_C_Linux_Fork_Exec_Ipc - Fatal编程技术网

我应该使用什么方法来知道哪些FD在进程分叉之后打开,然后是EXEC

我应该使用什么方法来知道哪些FD在进程分叉之后打开,然后是EXEC,c,linux,fork,exec,ipc,C,Linux,Fork,Exec,Ipc,我知道fork和exec家族会在执行后保留文件描述符。这种行为符合我的需要。另请参阅exec手册: exec()函数族替换当前进程映像 使用新的进程映像 所以,如果我做对了,在进程分叉之后,然后执行,程序需要额外的方法来了解哪些FD是打开的 我寻求的是一种简单的方法,将要使用的FD(加上需要关闭的FD)传递给新流程 作为旁注。在Windows中,您只能看到进程正在使用的FD列表。要做到这一点,您需要转到较低的级别。没有一个系统调用只为您提供打开的文件描述符列表。但是你要解决的更大的问题可以用几种

我知道fork和exec家族会在执行后保留文件描述符。这种行为符合我的需要。另请参阅exec手册:

exec()函数族替换当前进程映像 使用新的进程映像

所以,如果我做对了,在进程分叉之后,然后执行,程序需要额外的方法来了解哪些FD是打开的

我寻求的是一种简单的方法,将要使用的FD(加上需要关闭的FD)传递给新流程


作为旁注。在Windows中,您只能看到进程正在使用的FD列表。要做到这一点,您需要转到较低的级别。

没有一个系统调用只为您提供打开的文件描述符列表。但是你要解决的更大的问题可以用几种不同的方法来解决。最典型的两种方式是:

如果子级只处理一个客户端,那么只需让它从其stdin(fd0)读取并写入其stdout(fd1);分叉之后但在执行之前,您可以使用
dup2
将适当的文件描述符重新分配给数字0和1,不使用fd 2(stderr),并关闭所有其他描述符(或者您可以提前使用
O_CLOEXEC
/
fd_CLOEXEC
,这样您就不必这样做)。有些UNIX有一个方便的函数,名为“代码> CuthEng/<代码>,它关闭所有数值大于或等于其参数的文件描述符,但其他Unix拒绝采用它,原因是我认为完全是伪造的。

如果孩子正在与封装在一个文件描述符中的套接字或其他全双工通信通道通话,您仍应将其分配为fds 0和1,因为这样可以正常使用
stdin
stdout
文件对象(直到您需要使用
recvfrom
shutdown
等的时候),因为如果FD 0、1和2中的任何一个未打开,许多库都会感到困惑

该策略以最小的工作量提供了良好的并行度,并允许子程序与
inetd
和类似的多路复用器一起使用

如果子级需要处理多个客户端,请不要将任何客户端指定为fds 0或1;而是将要处理的客户端套接字列表以逗号分隔作为命令行参数传递。子级应仅注意这些文件描述符,而忽略所有其他文件描述符,即使它们已打开。(在分叉之后但在执行之前,您仍应尽最大努力关闭所有不相关的FD。)

在子系统中为多个客户端多路复用I/O需要更多的编程;如果您需要这样做,我强烈建议您使用已经有人为您编写的异步I/O库,例如
libevent
libuv


在你确实需要知道哪些FD是开放的,而你的父母没有给你任何线索的情况下,你有一个坏的和不可移植的选择,还有一个可怕的但可移植的选择

错误且不可移植的选项是打开并扫描目录
/proc/self/fd
。如果此目录存在,则其条目对应于进程中打开的文件描述符,其名称是十进制的描述符编号。这是一个错误的选项,因为您必须循环调用
readdir
,并注意避免fd支持您正在使用的
DIR
句柄,并且它是不可移植的,因为据我所知,只有Linux实现了这个特殊的目录,而且它可能对您不可用


可怕但可移植的选项是使用
getrlimit(RLIMIT_NOFILE)
查询最大文件描述符编号,然后调用
fcntl(i,F_GETFD)
从0循环到该编号,如果fd打开,则返回非负数;如果fd关闭,则返回负数(并将errno设置为EBADF)。这在任何地方都有效,但速度可能非常慢,特别是如果最大文件描述符数量很大。

如果确实需要,将其作为过程参数传递。或者在
exec
之前关闭它们,为什么需要它们?如果不想在子系统中打开它们,请使用
O\u CLOEXEC
打开它们,或者使用
fcntl()
在事件发生后添加标志。无需告诉孩子关闭它们。@EugeneSh。作为一个兼职项目,我的任务是做一个服务器。服务器将使用epoll做套接字,并根据协议请求做一些文件I/O。我在想这样一种方法,它将增加文件I/O吞吐量。因此服务器将接受套接字,执行请求/响应e状态机,然后fork来处理I/O。对于这样一个完整的答案,我觉得有义务告诉我更多关于我的任务。我一回到家/有空闲时间就去做。无论如何,谢谢。@e对已收到答案的问题的重大更改。如果回答者不理解您试图提出的问题,则会有一些回旋余地,但我得到的印象是我确实回答了这个问题……还是我回答了?是的,您回答了这个问题。必须补充一点,我需要处理每个用户(客户端)的多个文件I/O。建议使用一些事件多路复用库,我只是想自己制作一些东西。@zwol:您是否考虑过将零
事件
分块使用,比如几百到一千个描述符,以查找开放描述符(在指定范围内,或从0到
getrlimit(RLIMIT_NOFILE)
)?对于所有非开放描述符,
revents
将是
POLLNVAL
。由于
poll()
是POSIX.1-2001,它应该在大多数Unixy系统中可用。@NominalAnimal不,我没有想到,这很聪明,你想写第二个答案来描述它吗?