以下是崩溃的示例代码:
#include <stdio.h>
#include <poll.h>
#include <stdlib.h>
#include <limits.h>
#define POLL_SIZE 1024
int main(int argc, const char * argv[]) {
printf("%d\n", OPEN_MAX);
struct pollfd *poll_ = calloc(POLL_SIZE, sizeof(struct pollfd));
if (poll(poll_, POLL_SIZE, -1) < 0)
if (errno == EINVAL)
perror("poll error");
return 0;
}
如果将POLL_SIZE
设置为256或更低,代码就可以正常工作。有趣的是,如果你在Xcode中运行这个代码,它会正常执行,但如果你自己运行二进制文件就会崩溃。
输出如下:
10240
poll error: Invalid argument
根据poll(2)
:
[EINVAL] The nfds argument is greater than OPEN_MAX or the
timeout argument is less than -1.
正如您所看到的,POLL_SIZE
比限制小很多,超时正好是-1,但它崩溃了。
我用于手动构建的clang版本:
Configured with: prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/c++/4.2.1
Apple LLVM version 8.1.0 (clang-802.0.41)
Target: x86_64-apple-darwin16.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
答案 0 :(得分:1)
在Unix系统上,processes对资源有限制。参见例如getrlimit。您可以更改它们(使用setrlimit
),您的系统管理员也可以更改它们(例如,在启动或登录时配置这些限制)。与文件描述符有关的限制RLIMIT_NOFILE
。另请阅读ulimit
bash builtin。另请sysconf与_SC_OPEN_MAX
。
poll系统调用给出了一个不太大的数组,并且在其中重复一些file descriptor是不好的(可能但效率低下)。因此,在实践中,您经常使用一个非常小的数组来提及不同的(但有效)文件描述符。 poll
的第二个参数是有用条目的数量(实际上,所有不同的条目),而不是数组的分配大小。
您可以处理许多文件描述符。阅读C10K problem。
顺便说一句,你的代码没有崩溃。poll
记录失败(但没有崩溃)。
你应该阅读一些POSIX编程书。 Advanced Linux Programming是免费提供的,其中大部分是在POSIX(而不是Linux特定的)上。