web-dev-qa-db-ja.com

ループ内のselect()にFD_SET / FD_ZEROがあるのはなぜですか?

ソケット間の通信にselect機能を使用しています。 whileループがありますが、-

    while(!done) {

    FD_ZERO(&read_flags);
    FD_ZERO(&write_flags);
    FD_SET(comm_fd1, &read_flags);
    FD_SET(comm_fd2, &read_flags);
    FD_SET(STDIN_FILENO, &read_flags);
    FD_SET(comm_fd1, &write_flags);
    FD_SET(comm_fd2, &write_flags);
    FD_SET(STDIN_FILENO, &write_flags);

    //call select
    sel = select(comm_fd1+comm_fd2+1, &read_flags, &write_flags, (fd_set*)0, &waitd);

クライアント側のさまざまな変数でも同じです。私はこの基本的なテクニックをオンラインのチュートリアルから入手し、それを使用しました。それからそれは私を襲った-なぜ私はループするたびにセットをクリアしてファイル記述子を追加するのですか?それらがすでに追加されている場合、なぜそれらをクリアして再度追加するのですか?だから私はしばらく前にこれを一度だけやってみました、そしてコードはもう同じようには機能しません。誰かが理由を説明できますか? selectがセットの内容を変更するからですか?任意のヘルプおよび/または洞察力をいただければ幸いです。

23
Sterling

selectが戻ると、セットが更新され、読み取り/書き込み/例外の準備ができたファイル記述子が表示されます。他のすべてのフラグはクリアされました。

別の選択を開始する前に、クリアされたファイル記述子を再度有効にすることが重要です。そうしないと、それらのファイル記述子を待つ必要がなくなります。

再クリアに関しては、ファイル記述子のセットを変更する必要がある場合(新しく開いたソケットを読み取りセットに追加するなど)、クリアして再構築する必要があるため、始めるのは良い習慣です。毎回、プログラムの状態が変化しても正しいようにします。

25
Dave S

Selectがセットの内容を変更するからですか?

はい、selectが戻った後、準備ができた記述子のみがセット内に残ります。

5
Cat Plus Plus