提问人:Sean Champ 提问时间:11/6/2021 最后编辑:Sean Champ 更新时间:11/6/2021 访问量:55
如何在 Ruby 中访问FD_SETSIZE?生成 CPP (??)
How to access FD_SETSIZE in Ruby? spawn cpp (??)
问:
在阅读有关 Ruby 中的 IO 的信息时,此外,在一般对 POSIX 友好的 libc 环境中刷新我自己对 I/O 的了解有限,我在 Stack Overflow 上发现了一个问题:rubby 中的 poll()? 这样就提出了一个问题,即研究对象。
答复中提到了 Ruby 中一种方法的可用性。然而,它也引起了对在某些条件下在某些操作系统(包括 Linux)上使用的担忧,例如,当 Ruby 进程中可能打开了 1024 个或更多的文件描述符时。select
select
在对 ruby? 中的 poll() 问题的一些回答中,有人建议 if 在这样的环境中调用,可能会导致应用程序中的内存损坏。虽然在其他文档中,这种担忧可能没有表现出如此严重,并且可能有一种方法可以在这种情况下可移植地避免调用 - 正如后来的阅读所表明的那样 - 也许问题仍然是如何可移植地解决这个问题,对于 Ruby 的 .select
select
select
在阅读有关它的更多信息时,我注意到 Linux 上 select(2) 手册页的 “BUGS” 部分提供了可能代表对该问题的广泛讨论的内容。文本提到了一个常量,显然表示在调用时可以打开的文件描述符数量的排他性上限,因此可能期望在那时正常执行(粗略解释)。FD_SETSIZE
select
select
引用 select(2) 手册页:
POSIX allows an implementation to define an upper limit,
advertised via the constant FD_SETSIZE, on the range of file
descriptors that can be specified in a file descriptor set. The
Linux kernel imposes no fixed limit, but the glibc implementation
makes fd_set a fixed-size type, with FD_SETSIZE defined as 1024,
and the FD_*() macros operating according to that limit. To
monitor file descriptors greater than 1023, use poll(2) or
epoll(7) instead.
The implementation of the fd_set arguments as value-result
arguments is a design error that is avoided in poll(2) and
epoll(7).
According to POSIX, select() should check all specified file
descriptors in the three file descriptor sets, up to the limit
nfds-1. However, the current implementation ignores any file
descriptor in these sets that is greater than the maximum file
descriptor number that the process currently has open. According
to POSIX, any such file descriptor that is specified in one of
the sets should result in the error EBADF.
在 Ruby 中利用这一点,尽管可能是一种猜测:确定 Ruby 环境的最佳方法是什么?FD_SETSIZE
如果它作为常量可用,则假定该常量的值可以在任何打开的文件描述符上调用“select”之前在条件测试中使用。然后,Ruby 程序可能会在内部引发异常,然后调用任何等于或大于实例值的文件描述符,至少对于通常对 POSIX 友好的操作系统是这样?select
FD_SETSIZE
如果没有更简洁的方法来解决这个问题,也许可以将其用于项目的分发工具中,例如确定目标体系结构的常量值,然后将其与任何其他应用程序常量一起存储?我猜 a 可以用于此 - 无论是来自 GCC、LLVM 还是任何其他工具链 - 也许在某些方面类似于 sb-grovel。cpp
也许还有其他方法可以解决这个问题,而且是便携式的?也许在 Ruby 的某个地方已经有一个常数了?
也许在 Ruby 源代码中已经有一些关于它的检查?我想现在是时候寻找那个 GitHub 存储库了......
答:
Ruby 不会以任何方式导出FD_SETSIZE,因此检查大小的唯一方法是使用编译器。
与其构建自己的扩展,最省事的方法可能是使用 RubyInline,这使得检查变得非常简单:
gem install RubyInline
然后:
require 'inline'
class FdTest
inline do |builder|
builder.c "
long fd_setsize(void) {
return FD_SETSIZE;
}"
end
end
puts FdTest.new.fd_setsize
=> 1024
这甚至可以半移植到 Windows,前提是您在 WSL、Cygwin、MinGW 或类似的东西下运行。甚至可以在 Visual Studio 下工作,前提是它安装了 C 支持。
将其构建为扩展可能是确保更好兼容性的另一种解决方案,然后您可以为所需平台提供预编译的二进制文件。
这完全取决于您愿意经历多少麻烦才能在所有可能的平台上提取这些信息,因为实际上不存在完全独立于平台的解决方案。
评论
poll
epoll
(e)poll