回答
有两种方法可以在Unix主机上共享文件描述符。一种是让子进程在fork
之间继承它们。
另一个是通过一个Unix域套接字发送文件描述符sendmsg
;看到这个例子程序,功能send_connection
。请注意,文件描述符在接收过程中可能有不同的编号,因此您可能需要执行一些dup2
魔术才能使它们在共享内存中正确显示。
如果不这样做,共享内存区域中的文件描述符将只是整数。
最近,我不得不解决类似于OP所描述的问题。为此,我提出了一个专门的系统调用(我可能会添加一个非常简单的系统调用),将文件描述符直接发送到合作进程地址,并依靠Posix.1b信号队列作为传送介质(作为附加的好处,例如方法本质上不受“fd递归”攻击的影响,这种攻击在一定程度上困扰着所有基于VFS的机制)。
这里的建议补丁:
http://permalink.gmane.org/gmane.linux.kernel/1843084
(目前,该补丁仅增加了86/x86_64体系新的系统调用,但布线它到其他架构是平凡的,没有平台的依赖特性利用)。
操作理论如下。发送者和接收者都需要同意一个或多个信号号用于描述符传递。那些必须是Posix.1b信号,它保证可靠的交付,因此SIGRTMIN
抵消。此外,较小的信号数字具有较高的传送优先级,如果需要优先级管理:
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()
收集信号信息:
/* 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);
的sigwaitinfo()
成功返回后,sig_info.si_int
将包含新的文件描述符,指向与始发进程发送的文件描述符相同的IO对象。 sig_info.si_pid
将包含始发进程的PID,并且sig_info.si_uid
将包含始发进程的UID。如果sig_info.si_int
小于零(代表无效的文件描述符),则sig_info.si_errno
将包含errno
以表示在fd复制过程中遇到的实际错误。
- 1. 跨类共享值的Python描述符
- 2. execve()和共享文件描述符
- 3. 上的共享文件描述
- 4. 在不同进程之间共享打开的文件描述符
- 5. C中调用一个二进制文件(同时共享文件描述符)
- 6. 文件描述符和进程关系
- 7. 管叉:跨多个孩子共用一个文件描述符
- 8. 使用Android绑定器共享文件描述符
- 9. 跨进程共享位图
- 10. 不希望父进程和子进程共享同一个文件描述符表
- 11. 在fork之后,父进程和子进程是否共享由管道创建的文件描述符?
- 12. 在线程之间共享相同的epoll文件描述符可以吗?
- 13. 文件描述符饥饿和阻断文件描述符
- 14. 与Facebook共享描述编码问题
- 15. Facebook共享描述编码奇怪
- 16. Salesforce描述调用共享对象
- 17. 如何描述共享参考?
- 18. PAD(便携式应用描述)的共享文件/免费
- 19. 文件描述符是在Unix上是其本地进程还是全局文件描述符
- 20. Linux Socket文件描述符与线程
- 21. .Net Socket编程:文件描述符
- 22. 使用文件描述符过程
- 23. 在儿童完成一个exec之后与子进程共享文件描述符表
- 24. 资源共享,跨进程在磨床
- 25. 共享跨进程数据对象
- 26. 跨Java进程共享对象
- 27. 跨进程共享状态变量
- 28. 跨进程共享对象状态?
- 29. 跨多个进程的共享队列
- 30. c strcpy文件描述符
dup是否跨过程?这是一个进程可以重复其他进程'fd(指向它想指向的同一个文件),然后开始使用新的fd? – 2012-04-02 09:42:57
@SunandaSharma:不,在一个过程中克隆fds。我的意思是你必须同步各个进程中的fds的实际数字,然后使用'dup2'将它们设置为跨进程相同。 – 2012-04-02 09:49:42
哦,好吧。那么这个设置将不能为我工作,不幸的是。非常感谢您的投入:) – 2012-04-02 10:04:50