2009-06-19 22 views
1

スレッド間で共有されるグローバルリストに対する重い文字列の比較を行うため、アプリケーションの主なボトルネックとなる関数があります。私の質問は基本的にこれです:同じ関数内に複数のロックがある

1つの関数でリスト(List gList)を複数回ロックするのは悪いことですか?後で再びロックするには(ルックアップを行うときに基本的にロックする、新しいアイテムを挿入してロックを解除してから再度ロックして新しいアイテムを追加する)。

私はあなたがプロファイラーになっても、これに重い代償を払っているとは言えませんが、私は後の時点で、あるいは野生でコード化することができますか?誰もがこの中で最も実用的な、または個人的なexperenceを得た?

+0

また、そのリストから項目を変更したり削除したりしていますか? – BlackTigerX

答えて

1

それはあなたが検索し、挿入の間にロックを解除することにしたくないような音:

は、ここで簡単な使用例です。どちらか、またはルックアップ中にロックする必要はありません。

要素がまだ存在しない場合にのみリストに追加しようとしていますか?そうであれば、2つのステップ間でロックを解除することで、要素を準備している間に別のスレッドをリストに追加することができます。追加する準備が整う頃には、ルックアップが古くなっています。

ルックアップが古くなっていても問題ない場合は、ルックアップ中にロックする必要はないでしょう。

1

通常、可能な限り短時間ロックします。競合のコストは、競合のないロック取得のコスト(ユーザ空間で行うことができる)よりもはるかに高い(カーネルに移行する必要があります)ので、より細かいロックは通常、ロックをもっと長くする。

これは、適切な状況でプロファイルを作成していることを確認してください。これは、同時負荷が高いプロファイルです。さもなければあなたの結果は現実とほとんど関係がありません。

1

私の意見では、具体的な答えを示すデータはほとんどありません。一般に、ロックの数はパフォーマンスの問題ではなく、そのロックを待機しているスレッドの数です。

5

ロックをどのように実行しますか? ReaderWriterLockSlimを使用して調べることができます(まだそうでない場合)。

class SomeData 
{ 
    private IList<string> _someStrings = new List<string>(); 
    private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); 

    public void Add(string text) 
    { 
     _lock.EnterWriteLock();    
     try 
     { 
      _someStrings.Add(text); 
     } 
     finally 
     { 
      _lock.ExitWriteLock(); 
     } 

    } 

    public bool Contains(string text) 
    { 
     _lock.EnterReadLock(); 
     try 
     { 
      return _someStrings.Contains(text); 
     } 
     finally 
     { 
      _lock.ExitReadLock(); 
     } 
    } 
} 
+0

実際にはリストを変更していない限り、読み取り専用にロックする – jjxtra

関連する問題