他のすべてのスレッドがアクセスするマルチスレッドアプリケーションでTListを使用するのは安全ですが、1つのスレッドだけがそのスレッドに書き込みます。シナリオはDelphi TList in multithreading
他のスレッドがそれにアクセスしてそこからデータをフェッチするだけで、そのスレッドだけが書き込む個々のスレッドに一意のTListです。
安全ですか?
他のすべてのスレッドがアクセスするマルチスレッドアプリケーションでTListを使用するのは安全ですが、1つのスレッドだけがそのスレッドに書き込みます。シナリオはDelphi TList in multithreading
他のスレッドがそれにアクセスしてそこからデータをフェッチするだけで、そのスレッドだけが書き込む個々のスレッドに一意のTListです。
安全ですか?
同期しないと安全ではありません。読み込みスレッドは、書き込みスレッドがリストを変更するのと同時に、読み込みの途中にあってもよい。リストを変更することは、基礎となるメモリを再割り当てすることを意味します。
RTLはこのようなシナリオではTThreadList
クラスを提供します。各スレッドは、書き込みスレッドと読み取りスレッドの両方で、リストへのすべてのアクセスをLockList
とUnlockList
のペアでラップする必要があります。
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>
があります。
他の人が述べたように、TList
自体はスレッドセーフではありません。 TThreadList
(内部でクリティカルセクションを使用する)を使用するオーバーヘッドが心配されている場合は、既存のTList
コードをTMultiReadSingleWriteSynchronizer
、またはWin32 SRW lockでラップしてみてください。
hmm。それは私の心を打つことはありません、私はそれが安全だと思った場合は、1つのスレッドがそれに書き込みますが、あなたはちょうど解消した問題を考えなかった。だから私はtthreadlistを使用する必要があります。ありがとう –
私はindyのTIdThreadSafeListを使用します、私はちょうどロックとロック解除のアイデアをスキップしようとしていました。サーバー内に多くのスレッドフェイルリストがあり、それぞれの操作をロックすることは、あまりにも多くの時間がかかる可能性が高く、時間がかかり過ぎていると感じました。 –
これは、一度に1つのスレッドしかリストにアクセスできないため、競合が激しくなる可能性があります。リストに格納されているデータのタイプにもよりますが、ライターがアイテムを削除しない場合、最適な候補は、コンテンツのコピーを作成してロックを解除してから処理を実行するようにリーダーをコードすることですコピー。また、他のケースでは、複数のリーダー - 単一のライターアプローチで考えることもできます。 – jachguate