Monitor.Pulseおよび PulseAll では、操作対象のロックが呼び出し時にロックされている必要があります。この要件は不必要であり、パフォーマンスに悪影響を及ぼします。私の最初のアイデアは、これにより 2 つの無駄なコンテキスト スイッチが発生するというものでしたが、これは以下の nobugz によって修正されました (ありがとう)。モニターで待機していた他のスレッドが既にシェデュラーで使用可能であるため、コンテキスト スイッチが無駄になる可能性があるかどうかはまだわかりませんが、それらがスケジュールされている場合は、いくつかの命令しか実行できません。ミューテックスにヒットする前に、コンテキストを再度切り替える必要があります。Monitor.Pulse を呼び出す前にロックが解除されていれば、これははるかに単純で高速に見えます。
Pthread 条件変数は同じ概念を実装しますが、上記の制限はありません。ミューテックスを所有していなくても pthread_cond_broadcast を呼び出すことができます。これは、要件が正当化されていないことの証拠だと思います。
編集: Monitor.Pulse の前に通常変更される共有リソースを保護するには、ロックが必要であることを認識しています。モニターがこれをサポートしていることを考えると、リソースへのアクセス後、パルスの前にロックが解除された可能性があると言いたかったのです。これは、共有リソースがアクセスされる最短時間にロックを制限するのに役立ちます。そのような:
void f(Item i)
{
lock(somequeue) {
somequeue.add(i);
}
Monitor.Pulse(somequeue); // error
}