4

select複数のスレッドから同じ開いているファイル記述子を呼び出すとどうなりますか?

これはどこかに文書化されていますか?

4

2 に答える 2

7

POSIX 2008select仕様によると、2 つのスレッドが同時に呼び出すことを禁止するものは何もありませんselect

両方のスレッドが重複するファイル記述子のセットを監視しており、共通ファイル記述子の一部が読み取り可能または書き込み可能になるか、エラーが診断された場合、両方のスレッドが共通ファイル記述子の準備ができているというレポートを返す可能性があると推測するのは合理的です。これは保証できません。心配するタイミングの問題があり、スレッドのスケジューリングなどに依存する可能性があります。また、スレッドの1つが、読み取るデータが含まれていると伝えられたファイル記述子で読み取るデータを見つけられない可能性があることも意味します。他のスレッドが最初にそこに到達しました。データの特定のバイトは、スレッドの 1 つだけによって読み取られます。

于 2012-08-23T05:42:41.560 に答える
5

Linux のマニュアル ページによると、selectはスレッド セーフ機能であり、キャンセル ポイントです。

Linuxの一部のオペレーティング システムでは、1 つのスレッドが正常に に入り、select他のスレッドはブロックされます (の本体selectはクリティカル セクションです)。最初のスレッドにどのような記述子が返されても、正常に入る 2 番目のスレッドは、レベル トリガー インターフェイスであるselectため、おそらく同じセットですぐにウェイクアップします。select

したがって、これらのオペレーティング システムのLinux ではselect、ファイル記述子の複数のセットを同時に選択するために使用することはできません。

Linux は完全に再入可能な実行をサポートしているようで、このテスト プログラムで実証されています。

void * reader (void *arg) {
    int *fds = (int *)arg;
    struct timeval to = { 2, 0 };
    fd_set rfds;

    FD_ZERO(&rfds);
    FD_SET(fds[0], &rfds);

    select(fds[0]+1, &rfds, 0, 0, &to);
}

int main () {
    int sp[2];
    pthread_t t[2];
    socketpair(AF_UNIX, SOCK_STREAM, 0, sp);
    pthread_create(&t[0], 0, reader, sp);
    pthread_create(&t[1], 0, reader, sp);
    pthread_join(t[0], 0);
    pthread_join(t[1], 0);
    return 0;
}

このプログラムを Linux (私の場合は 2.6.43) で計測すると、プログラムは 2 秒後に戻り、両方のスレッドがselect同時に開始されたことを示しています。

于 2012-08-23T04:52:04.707 に答える