3

アクセス myst を同期して、一度に 1 つのスレッドのみを通過させるメソッドがあります。これが私の現在の実装です:

private Boolean m_NoNeedToProceed;
private Object m_SynchronizationObject = new Object();

public void MyMethod()
{
    lock (m_SynchronizationObject)
    {
        if (m_NoNeedToProceed)
            return;

今、私はそれを次のように少し変更することを考えていました:

private Boolean m_NoNeedToProceed;
private Object m_SynchronizationObject = new Object();

public void MyMethod()
{
    if (m_NoNeedToProceed)
        return;

    lock (m_SynchronizationObject)
    {

前のスレッドがメソッド呼び出しを完了するのを待たずに呼び出し元のスレッドが続行できるように、ロックする前にクイックリターンを実行する方がよいのではないでしょうか?

4

3 に答える 3

1

ロックする前にさっさと戻したほうがいいんじゃないかな…

いいえ。ロックは単なる相互排除メカニズムではなく、メモリ バリアでもあります1。ロックがないと、同時スレッドのいずれかが変数2を変更しようとすると、データ競合が発生する可能性があります。

ところで、競合がなければロックのパフォーマンスは良好であるため、とにかくパフォーマンスが大幅に向上することはありません。いつものように、パフォーマンス、特にこの「金属に近いもの」についての仮定は控えてください。迷ったら採寸!

...前のスレッドがメソッド呼び出しを完了するのを待たずに呼び出しスレッドを続行できるようにするには?

これは、ロックを必要以上に長く保持していることを意味します。共有メモリが保護を必要としなくなったらすぐにロックを解放します (メソッドの終了よりも早いかもしれません)。人為的にそれを回避しようとする必要はありません。


1つまり、すべての CPU コアが「同じ」メモリを参照するように、キャッシュ コヒーレンシ メカニズムをトリガーします。

2たとえば、1 つのスレッドが変数に書き込みますが、その変更は 1 つのコアの書き込みバッファーにしばらく残るため、他のコアの他のスレッドはすぐには認識しません。

于 2013-05-01T19:50:29.280 に答える
0

m_NoNeedToProceedはい、競合状態が関連付けられていない限り。

メソッドの実行に時間がかかり、一部のスレッドがメソッドのクリティカル セクションに実際にアクセスする必要がない場合。その場合は、ロックを取得せずに早く返してもらうのが最善です。

于 2013-05-01T19:33:13.203 に答える
0

はい、ロックする前にそれを行う方が良いです。

揮発m_NoNeedToProceed 性にする

免責事項: volatileはスレッドセーフにはなりません。別のプロセッサで値が変更されたかどうかをバリアに確認させるだけです。

于 2013-05-01T19:33:45.450 に答える