POLLNVAL ファイル記述子の値が無効であることを意味します。通常はプログラムのエラーを示しますが、poll に頼ることができます POLLNVAL を返す ファイル記述子を閉じて、それ以降ファイルを開いていない場合、記述子を再利用した可能性があります。
POLLERR select からのエラー イベントに似ています . read であることを示します または write 呼び出しはエラー状態 (I/O エラーなど) を返します。これには、select の帯域外データは含まれません。 errorfds 経由で信号を送る マスクしますが poll POLLPRI 経由のシグナル .
POLLHUP 基本的に、接続のもう一方の端にあるものが接続の端を閉じたことを意味します。 POSIX では
デバイスが切断されました。このイベントと POLLOUT は相互に排他的です。ハングアップが発生した場合、ストリームを書き込み可能にすることはできません。
これは端末にとって十分明らかです:端末がなくなった (SIGHUP を生成する同じイベント:モデム セッションが終了した、端末エミュレータ ウィンドウが閉じられたなど)。 POLLHUP 通常のファイルに対して送信されることはありません。パイプとソケットの場合は、オペレーティング システムによって異なります。 Linux は POLLHUP を設定します パイプの書き込み側のプログラムがパイプを閉じ、POLLIN|POLLHUP を設定したとき ソケットのもう一方の端がソケットを閉じたが、POLLIN ソケットのシャットダウンの場合のみ。最近の *BSD セット POLLIN|POLLUP パイプの書き込み側がパイプを閉じ、ソケットの動作がより可変になる場合。
POLLHUP ソケットが接続されていないことを意味します。 TCP では、これは FIN が送受信されたことを意味します。
POLLERR ソケットで非同期エラーが発生したことを意味します。 TCP では、これは通常、RST が受信または送信されたことを意味します。ファイル記述子がソケットでない場合、POLLERR デバイスがポーリングをサポートしていない可能性があります。
上記の両方の条件で、ソケット ファイル記述子はまだ開いており、まだ閉じられていません (しかし shutdown() 既に呼び出されている可能性があります)。 close() ファイル記述子で、ソケットに代わってまだ予約されているリソースを解放します。理論的には、ソケットをすぐに再利用できるはずです (たとえば、別の connect() 呼び出します)
POLLNVAL ソケットファイル記述子が開いていないことを意味します。 close() にするとエラーになります
それは正確なエラーの性質に依存します。 getsockopt() を使用して問題を確認してください:
int error = 0;
socklen_t errlen = sizeof(error);
getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&error, &errlen);
値:http://www.xinotes.net/notes/note/1793/
最も簡単な方法は、ソケットがいずれにしても使用できなくなったと想定して閉じることです。
最小限の FIFO の例
これらの状況がいつ発生するかを理解すれば、対処法も簡単にわかるはずです。
poll.c
#define _XOPEN_SOURCE 700
#include <fcntl.h> /* creat, O_CREAT */
#include <poll.h> /* poll */
#include <stdio.h> /* printf, puts, snprintf */
#include <stdlib.h> /* EXIT_FAILURE, EXIT_SUCCESS */
#include <unistd.h> /* read */
int main(void) {
char buf[1024];
int fd, n;
short revents;
struct pollfd pfd;
fd = open("poll0.tmp", O_RDONLY | O_NONBLOCK);
pfd.fd = fd;
pfd.events = POLLIN;
while (1) {
puts("loop");
poll(&pfd, 1, -1);
revents = pfd.revents;
if (revents & POLLIN) {
n = read(pfd.fd, buf, sizeof(buf));
printf("POLLIN n=%d buf=%.*s\n", n, n, buf);
}
if (revents & POLLHUP) {
printf("POLLHUP\n");
close(pfd.fd);
pfd.fd *= -1;
}
if (revents & POLLNVAL) {
printf("POLLNVAL\n");
}
if (revents & POLLERR) {
printf("POLLERR\n");
}
}
}
GitHub アップストリーム。
コンパイル:
gcc -o poll.out -std=c99 poll.c
使い方:
sudo mknod -m 666 poll0.tmp p
./poll.out
別のシェル:
printf a >poll0.tmp
ポルハップ
ソースを変更しない場合:./poll.out 出力:
loop
POLLIN n=1 buf=a
loop
POLLHUP
loop
そう:
POLLIN入力が利用可能になったときに発生POLLHUPファイルがprintfによって閉じられたときに発生しますclose(pfd.fd);とpfd.fd *= -1;クリーンアップすると、POLLHUPの受信が停止しますpoll永久にハングアップ
これは通常の操作です。
次の open を待つために FIFO を再登録できるようになりました。 、または完了したらループを終了します。
世論調査
pfd.fd *= -1; をコメントアウトすると :./poll.out プリント:
POLLIN n=1 buf=a
loop
POLLHUP
loop
POLLNVAL
loop
POLLNVAL
...
永遠にループします。
そう:
POLLINとPOLLHUPとclose以前のように起こったpfd.fdを設定していないため 負の数pollfdを使用しようとし続けます- これは
POLLNVALを返し続けます 永遠に
したがって、これは発生すべきではなかったことがわかり、コードにバグがあることを示しています。
ポーラー
POLLERR を生成する方法がわかりません FIFOで。方法があれば教えてください。しかし、file_operations で可能なはずです
Ubuntu 14.04 でテスト済み。