是否有可移植的方式(POSIX)来获取当前进程的最高分配文件描述符号?
我知道在AIX上有一个很好的方法来获取数字,但我正在寻找一种可移植的方法.
我问的原因是我想要关闭所有打开的文件描述符.我的程序是一个以root用户身份运行的服务器,为非root用户分叉和执行子程序.在子进程中保留特权文件描述符是一个安全问题.有些文件描述符可能是由我无法控制的代码(C库,第三方库等)打开的,所以我不能依赖它们FD_CLOEXEC.
我在掌握如何正确处理从多线程程序中以多线程方式使用Boost Asio创建子进程时遇到了一些麻烦.
如果我理解正确,在Unix世界中启动子进程的方法是调用fork()后跟一个exec*().此外,如果我理解正确,调用fork()将复制所有文件描述符等等,这些需要在子进程中关闭,除非标记为FD_CLOEXEC(并因此在调用时原子关闭exec*()).
Boost Asio需要在fork()调用时通知,以便通过调用正确操作notify_fork().但是,在多线程程序中,这会产生几个问题:
如果我理解正确,套接字默认由子进程继承.它们可以设置为SOCK_CLOEXEC- 但不能直接创建*,因此如果从另一个线程创建子进程,则会导致计时窗口.
notify_fork()要求没有其他线程调用任何其他io_service函数,也不要求任何其他任何与该函数关联的I/O对象上的函数io_service.这似乎并不可行 - 毕竟程序是多线程的.
如果我理解正确,任何函数调用之间fork()和exec*()需要异步信号安全(请参阅fork()文档).没有notify_fork()异步信号安全呼叫的文档.事实上,如果我查看Boost Asio的源代码(至少在版本1.54中),可能会调用pthread_mutex_lock,如果我理解正确的话,这不是异步信号安全的(参见Signal Concepts,还有其他调用正在进行中)不在白名单上).
问题#1我可以通过分离子进程和套接字+文件的创建来解决这个问题,这样我就可以确保在创建的套接字和设置之间的窗口中没有创建子进程SOCK_CLOEXEC.问题#2比较棘手,我可能需要确保所有 asio处理程序线程都已停止,执行fork然后再次重新创建它们,这充其量是潮流,并且在最坏的情况下真的很糟糕(我的挂起计时器怎么样? ).问题#3似乎完全无法正确使用它.
如何在多线程程序中与fork()+ 一起正确使用Boost Asio exec*()?
......还是我"分叉"?
如果我误解了任何基本概念,请告诉我(我在Windows编程时提出,而不是*nix ......).
编辑:* - 实际上可以SOCK_CLOEXEC直接在Linux上创建带有set的套接字,自2.6.27起可用(参见socket() …