2017-04-22 91 views
-1

返回EINVAL超过256所描述这里是一个崩溃的示例代码:民意调查()在MacOS

#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,但它坠毁了。

我使用的人工建筑

我铛版本:

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 
+1

您是否阅读过[手册页](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man2/poll.2.html)?它对“EINVAL”有何评论? OPEN_MAX的价值是什么? –

+1

另请参见[getrlimit](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man2/getrlimit.2.html) –

+1

实际上,您经常使用'poll'不是太大的一组文件描述符,并且提到了几次 - 在传递给poll的数组中,* same *文件描述符(例如0)是不好的味道。所以在实践中它并不重要,它肯定是一个系统管理员问题。但是请阅读[C10K问题](https://en.wikipedia.org/wiki/C10k_problem) –

回答

1

在Unix系统中,processes对资源的限制。见例如getrlimit。您可以更改它们(使用setrlimit),您的系统管理员也可以更改它们(例如,在启动或登录时配置这些限制)。与文件描述符有关的限制RLIMIT_NOFILE。另请阅读关于ulimitbash builtin。请参阅sysconf_SC_OPEN_MAX

poll系统调用给出了一个不太大的数组,并且在其中重复一些file descriptor是一种糟糕的品味(可能,但效率低)。所以在实践中你会经常用一个很小的数组来提及不同的(但是有效的)文件描述符。 poll的第二个参数是有用条目的数量(实际上,全部不同),而不是数组的分配大小。

您可能会处理很多文件描述符。阅读有关C10K problem

顺便说一句,你的代码不会崩溃。 poll由于记录失败(但没有崩溃)。

您应该阅读一些POSIX编程手册。 Advanced Linux Programming是免费提供的,其中大部分是在POSIX(而不是Linux专用)上。