0

マルチスレッドの epoll サーバーを使用しています。epoll fd を作成すると、X スレッドがスリープ状態になり、その同じ epoll fd からのイベントを待機epoll_wait()ます。

ここで私の質問は次のとおりです。N > 1 && N < X で、N 個のスレッドをウェイクアップするにはどうすればよいですか?

これまで、Linux 固有の eventfd 機能を使用してきました。これは 1 つのスレッドだけでかなりうまく機能しましたが、複数のスレッドが同じ epoll fd を待機している、問題が発生します。

ケース 1) LT: 「レベル トリガー」モードで eventfd を追加すると、eventfdへの書き込み時にすべてのスレッドが起動します。これは、レベル トリガー モードがどのように機能するかです。

N = X

ケース 2) ET: 「エッジ トリガー」モードで eventfd を追加すると、eventfdに書き込むときに1 つのスレッドのみが起動します。これがエッジ トリガー モードのしくみEAGAINですread(eventfd, ...);

N = 1

ケース 3) セルフパイプ トリックも試しましたが、パイプに N 回書き込むと N スレッドが起動します。信頼性が低く、1 つのスレッドがパイプから 2 つの「トークン」を読み取ることもあれば、1 つまたは 3 つ読み取ることもあります。

N = ランダム

私が試したすべてのケースで、N=N だけを取得することはできません。N スレッドのみを起動することはできませんが、1、ALL、または RANDOM のいずれかです。私は何が欠けていますか?何かご意見は?EFD_SEMAPHORE注:そこからの助けなしに、eventfd固有のフラグも試しました。

4

2 に答える 2

1

eventfdマニュアルページによると。


カウンタの値が 0 より大きい場合、ファイル記述子は読み取り可能です (select(2) readfds 引数、poll(2) POLLIN フラグ) 。

EFD_SEMAPHOREフラグ付きの eventfd を作成することにより:

(if) eventfd カウンターの値が 0 以外の場合、read(2) は値 1 を含む 8 バイトを返し、カウンターの値は 1 減らされます。


セマフォ (EFD_SEMAPHOREフラグ)、NONBLOCK (EFD_NONBLOCKフラグ) の eventfd を使用し、レベル トリガーepoll()またはノーマルで待機しますpoll()

ウェイクアップしたいN 個eventfd_write(fd, N)のスレッドを記述します。

スレッドが起動したら、read(). エラーが発生した場合は、 N回の読み取りが成功したEAGAINため、スリープ状態に戻る可能性があります。したがって、 N 個のスレッドは、スリープ状態を維持する必要があることを認識しています。

短所

すべてのスレッドが起動します (大群の問題)。

于 2018-03-11T20:13:17.650 に答える