0

私は pthread 条件変数 (Linux futex に基づく) を実装しておりpthread_cond_broadcast、プロセス共有条件変数での「スタンピード効果」を回避するためのアイデアがあります。非プロセス共有条件変数の場合、futex 再キューイング操作は伝統的に (つまり NPTL によって) ウェイターを起動せずに cond 変数の futex からミューテックスの futex に再キューイングするために使用されますが、これは一般にプロセス共有条件変数では不可能です。pthread_cond_broadcast関連するミューテックスへの有効なポインターがない可能性があるためです。最悪のシナリオでは、ミューテックスがそのメモリ空間にマップされていない可能性さえあります。

この問題を克服するための私の考えはpthread_cond_broadcast、ミューテックスへの必要なポインターがあるため、ウェイターを 1 つだけ直接ウェイクし、そのウェイターがウェイクアップ時にリキュー操作を実行することです。

当然のことながら、このアプローチを追求する場合、考慮すべき多くの醜い競合状態がありますが、それらを克服できる場合、そのような実装が無効または望ましくない他の理由はありますか? 克服できないかもしれないと私が考えることができる1つの潜在的な問題は、リキューを担当するウェイター(別のプロセス)が動作する前に殺されるレースですが、condvarを配置することでこれでも克服できるかもしれません堅牢なミューテックス リストに futex を追加して、プロセスが終了したときにカーネルがウェイクを実行できるようにします。

4

2 に答える 2

2

複数のアドレス空間に属するウェイターが存在する可能性があり、それぞれがメモリ内の異なるアドレスで futex に関連付けられたミューテックスをマップしています。FUTEX_REQUEUEリキューポイントがすべてのウェイターで同じアドレスにマップされていない可能性がある場合に安全に使用できるかどうかはわかりません。もしそうなら、これは問題ではありません。

堅牢な futex では検出されない問題が他にもあります。たとえば、選択したウェイターがシグナル ハンドラーでビジー状態である場合、任意に長い時間待たされる可能性があります。[コメントで議論されているように、これらは問題ではありません]

堅牢な futex では、futex の値を& 0x3FFFFFFF起動するスレッドの TID に設定する必要があることに注意してください。FUTEX_WAITERSウェイクアップが必要な場合は、ビットをオンにする必要もあります。これは、ブロードキャスト スレッドからどのスレッドを起こすかを選択する必要があることを意味しますFUTEX_WAKE。また、ウェイカー スレッドがその TID を状態変数に書き込む直前にスレッドが停止する可能性にも対処する必要があります。おそらく、堅牢なミューテックス システムにも登録されている「保留中のマスター」フィールドを用意することをお勧めします。

スレッド終了の問題を慎重に処理する限り、これが機能しない理由はわかりません。FUTEX_WAITとはいえ、リキュー ポイントと比較値を引数として受け取る拡張機能をカーネルで単純に定義し、カーネルに単純で競合のない方法でこれを処理させるのが最善かもしれません。

于 2011-09-24T03:38:55.017 に答える