2011-09-19 23 views
2

マルチスレッドアプリケーションで読み書きされるアイテムのコレクションがあるとします。いくつかのアイテムにアルゴリズムを適用する場合は、ロックを取得するためのさまざまな方法があります。このように、後で処理するアイテムのスレッドセーフなコレクションを取得するためにコレクションをロックする最も良い方法は何ですか?

for each thing in things 
{ 
    lock(collection) 
    { 
     get the item from collection that matches thing 
    } 
    do stuff with item 
} 

またはオンデマンドでロックすることで、コレクションを持つ:需要をロックオンすることにより

lock(collection) 
{ 
    for each thing in things 
    { 
     get the item from collection that matches thing 
     do stuff with item 
    } 
} 

:全体の操作中にロックすることにより

少ない時間でロックされます:

Items items 
for each thing in things 
{ 
    lock(collection) 
    { 
     get the item from collection that matches thing 
    } 
    items.Add(item) 
} 
for each item in items 
{ 
    do stuff with item 
} 

各項目に適用された実際のアルゴリズムにつきますが、あなたは何をしますか?私はC + +を使用していますが、私はかなり無関係であると確信しています。

答えて

2

ロックの下のコレクション/フィールドに別のフィールドを含むDouble Check lockパターンを見てください。デビッドHeffernanのは​​議論

+0

この方法にかかわらず、私の場合はどうしますか? –

+0

更新された答えを見てください。アイデアは、コレクションと一緒に別のフィールド/変数を導入し、この特定のフィールドをロックすることです。コレクションまたは各要素をロックするインスタント(前者は混乱しています) – sll

+0

"double check locking is broken"宣言。 –

0

ロックの取得と解放は高価です。ループ内の個々の要素ではなく、コレクション全体をロックします。操作全体がアトミックである必要がある場合は意味があります。

2

で見てみる述べたように :

また、それは価値があるコレクション

EDITを更新し、他のスレッドながら読んだことができますReaders-writer lock技術を見てみることをスレッドの読み書きのマルチスレッド設定では、最初の例と第2の例は異なる意味を持ちます。 3番目の例は、「アイテムで何かをする」が他のスレッドとやりとりする場合、さらに別の意味を持つことができます。

コードの実行方法を決める前に、コードで実行する操作を決定する必要があります。

+0

"do something with something"は他のスレッドとやりとりしますが、私のアイテムのコレクションを使用するスレッドとはやり取りしません。 –

関連する問題