2017-04-22 68 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專用)上。