Python 2.4.3 では FD_SETSIZE 以上のファイルディスクリプタを扱えない
Mac でやってて嵌ったのでメモ。
Python 2.4.3 の Modules/socketmodule.c を見ると、send/recv/accept なんかにこんなコードがある。
if (!IS_SELECTABLE(s)) return select_error();
select_error はエラー文字列を設定するだけのコード。
で、IS_SELECTABLE がこんな感じ。
/* Can we call select() with this socket without a buffer overrun? */ #ifdef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE /* Platform can select file descriptors beyond FD_SETSIZE */ #define IS_SELECTABLE(s) 1 #else /* POSIX says selecting file descriptors beyond FD_SETSIZE has undefined behaviour. */ #define IS_SELECTABLE(s) ((s)->sock_fd < FD_SETSIZE) #endif
Blocking I/O だろうと Non-Blocking I/O だろうと、上記の IS_SELECTABLE によるチェックが行われるので、Blocking I/O で select を使わない場合もエラーになってしまうというオチ。たいていの場合、FD_SETSIZE は 1024 だから、同時に、1,000個程度のコネクションを張ると、理論上は扱えるのに、Python ではエラーになってとまってしまうという現象になる。
まぁ、Blocking I/O で 1,000 個以上のコネクションを同時に扱うなんてことは普通はやらないから特に問題にはならないだろうけど。2.4.4/2.5 では直っているし。