2013-01-20 15 views
6

他のすべてのスレッドがアクセスするマルチスレッドアプリケーションでTListを使用するのは安全ですが、1つのスレッドだけがそのスレッドに書き込みます。シナリオはDelphi TList in multithreading

他のスレッドがそれにアクセスしてそこからデータをフェッチするだけで、そのスレッドだけが書き込む個々のスレッドに一意のTListです。

安全ですか?

答えて

10

同期しないと安全ではありません。読み込みスレッドは、書き込みスレッドがリストを変更するのと同時に、読み込みの途中にあってもよい。リストを変更することは、基礎となるメモリを再割り当てすることを意味します。

RTLはこのようなシナリオではTThreadListクラスを提供します。各スレッドは、書き込みスレッドと読み取りスレッドの両方で、リストへのすべてのアクセスをLockListUnlockListのペアでラップする必要があります。

var 
    ThreadList: TThreadList;//declared in some shared location 
.... 
//each thread accesses the list like this: 
var 
    List: TList; 
.... 
List := ThreadList.LockList; 
try 
    .... do stuff with List 
finally 
    ThreadList.UnlockList; 
end; 

ジェネリックをサポートするDelphiを使用している場合は、汎用バージョンTThreadList<T>があります。

+0

hmm。それは私の心を打つことはありません、私はそれが安全だと思った場合は、1つのスレッドがそれに書き込みますが、あなたはちょうど解消した問題を考えなかった。だから私はtthreadlistを使用する必要があります。ありがとう –

+0

私はindyのTIdThreadSafeListを使用します、私はちょうどロックとロック解除のアイデアをスキップしようとしていました。サーバー内に多くのスレッドフェイルリストがあり、それぞれの操作をロックすることは、あまりにも多くの時間がかかる可能性が高く、時間がかかり過ぎていると感じました。 –

+0

これは、一度に1つのスレッドしかリストにアクセスできないため、競合が激しくなる可能性があります。リストに格納されているデータのタイプにもよりますが、ライターがアイテムを削除しない場合、最適な候補は、コンテンツのコピーを作成してロックを解除してから処理を実行するようにリーダーをコードすることですコピー。また、他のケースでは、複数のリーダー - 単一のライターアプローチで考えることもできます。 – jachguate

5

他の人が述べたように、TList自体はスレッドセーフではありません。 TThreadList(内部でクリティカルセクションを使用する)を使用するオーバーヘッドが心配されている場合は、既存のTListコードをTMultiReadSingleWriteSynchronizer、またはWin32 SRW lockでラップしてみてください。

関連する問題