次のコードは、Windows では正しく動作しません (Linux では動作します)。
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(True)
sock.connect(address)
gobject.io_add_watch(
sock.fileno(),
gobject.IO_OUT | gobject.IO_ERR | gobject.IO_HUP,
callback)
glib ソースのさまざまな場所にあるコメントのスニペットや、他の場所で、Windows ではポーリング中にソケットが非ブロック モードになることが言及されています。その結果、コールバックself.outgoing_cb
が常に呼び出され、ソケットへの書き込みが次のエラー メッセージで失敗します。
[Errno 10035] A non-blocking socket operation could not be completed immediately
書き込み前の呼び出しsock.setblocking(True)
は、これを回避するようには見えません。ポーリングの優先順位を下げ、エラー メッセージを無視すると、期待どおりに動作しますが、多くのイベントがスローされ、多くの CPU が消費されます。Windows でこの制限を回避する方法はありますか?
アップデート
指摘するかもしれませんが、ポーリングの全体的なポイントはPOLLOUT
、書き込み呼び出しを行ったときにEAGAIN
/を取得できないことEWOULDBLOCK
です。私が受け取っている奇妙なエラー メッセージは、これら 2 つのエラー コードに相当する Windows のものだと思います。言い換えれば、gobject.IO_OUT
ソケットが正常に書き込みを許可しない場合にイベントを取得していますが、それをブロック モードにすると、この不適切なエラーが発生します。
別のアップデート
これが正しく機能する Linux では、ソケットは非ブロッキング モードに切り替えられず、ソケットがIO_OUT
ブロックせずに、またはエラーをスローせずに書き込みを許可するときに を受け取ります。Windowsでエミュレート/復元したいのはこの機能です。
その他の注意事項
からman poll
:
poll() performs a similar task to select(2): it waits for one of a set
of file descriptors to become ready to perform I/O.
POLLOUT
Writing now will not block.
からman select
:
A file descriptor is considered ready if it is possible to perform the corre‐
sponding I/O operation (e.g., read(2)) without blocking.