File 跨进程共享文件描述符
我想为多个独立进程设置一个共享内存环境。在我想要共享的数据结构中,还有每个进程的连接FD 我想知道我们是否有办法分享这些FD?或者使用全球fds或类似的东西File 跨进程共享文件描述符,file,shared-memory,File,Shared Memory,我想为多个独立进程设置一个共享内存环境。在我想要共享的数据结构中,还有每个进程的连接FD 我想知道我们是否有办法分享这些FD?或者使用全球fds或类似的东西 提前谢谢 在Unix主机上共享文件描述符有两种方法。一种是让子进程跨fork继承它们 另一种方法是使用sendmsg通过Unix域套接字发送文件描述符;请参阅此示例程序,函数(已存档)。请注意,文件描述符在接收过程中可能有不同的编号,因此您可能需要执行一些dup2魔术,使它们正好出现在共享内存中 如果不这样做,共享内存区域中的文件描述符将只
提前谢谢 在Unix主机上共享文件描述符有两种方法。一种是让子进程跨
fork
继承它们
另一种方法是使用sendmsg
通过Unix域套接字发送文件描述符;请参阅此示例程序,函数(已存档)。请注意,文件描述符在接收过程中可能有不同的编号,因此您可能需要执行一些dup2
魔术,使它们正好出现在共享内存中
如果不这样做,共享内存区域中的文件描述符将只是整数。最近,我不得不解决一个类似于OP描述的问题。为此,我提出了一个专门的系统调用(我可能会添加一个非常简单的调用),将文件描述符直接发送到协作进程地址,并依赖Posix.1b信号队列作为传递介质(另外一个好处是,这种方法天生不受“fd递归”的影响)攻击,这在某种程度上困扰着所有基于VFS的机制) 以下是建议的修补程序: (目前,该补丁只为x86/x86_64体系结构添加了新的系统调用,但将其连接到其他体系结构并不重要,没有使用依赖于平台的功能) 操作理论如下。发送方和接收方都需要商定一个或多个用于描述符传递的信号号。这些信号必须是Posix.1b信号,保证可靠传输,因此
SIGRTMIN
offset。此外,如果需要优先级管理,较小的信号号具有较高的传输优先级:
int signo_to_use = SIGRTMIN + my_sig_off;
然后,发起进程调用一个系统调用:
int err = sendfd(peer_pid, signo_to_use, fd_to_send);
就这样,发送方不需要其他任何东西。显然,sendfd()
还必须注意,sendfd()
从不阻塞;如果目标进程的信号队列已满,它将立即返回。在一个设计良好的应用程序中,这将表明目标进程无论如何都有问题,或者有太多的工作要做,因此应该产生新的工作人员/丢弃工作项。进程信号队列的大小可以使用rlimit()
配置,与可用文件描述符的数量相同
接收过程可以安全地忽略信号(在这种情况下不会发生任何事情,内核端几乎不会产生任何开销)。但是,如果接收进程想要获得传递的文件描述符,它所需要做的就是使用sigtimedwait()
/sigwaitinfo()
或更通用的signalfd()
收集信号信息:
成功返回sigwaitinfo()
后,sig_info.si_int
将包含新的文件描述符,指向与原始进程发送的文件描述符相同的IO对象sig_info.si_pid
将包含发起进程的pid,sig_info.si_uid
将包含发起进程的uid。如果sig\u info.si\u int
小于零(表示无效的文件描述符),sig\u info.si\u errno
将包含fd复制过程中遇到的实际错误的errno
。dup是否跨进程工作?也就是说,一个进程可以复制另一个进程的fd(指向它想要指向的同一个文件),然后开始使用新的fd吗?@SunandaSharma:no,dup
在单个进程内克隆fd。我的意思是,您必须同步FD在各个进程中的实际数字,然后使用dup2
将它们设置为跨进程相同。哦,好的。很遗憾,这个设置将无法为我工作。非常感谢您的投入:)
/* First, the receiver needs to specify what it is waiting for: */
sigset_t sig_mask;
sigemptyset(&sig_mask);
sigaddset(&sig_mask, signo_to_use);
siginfo_t sig_info;
/* Then all it needs is to wait for the event: */
sigwaitinfo(&sig_mask, sig_info);