2013-01-20 12 views
6

Ist es sicher, TList in einer Multithread-Anwendung zu verwenden, auf die alle anderen Threads zugreifen, aber nur ein Thread schreibt. Das Szenario istDelphi TList in Multithreading

Eine eindeutige TList für jeden Thread, in den nur dieser Thread schreibt, während andere Threads nur darauf zugreifen, um Daten von ihm abzurufen.

Ist es sicher?

Antwort

10

Das ist ohne Synchronisation nicht sicher. Die Lese-Threads können in der Mitte eines Lesevorgangs sein, während der Schreib-Thread die Liste ändert. Und das Ändern der Liste kann bedeuten, den zugrunde liegenden Speicher neu zuzuweisen.

Die RTL bietet die TThreadList Klasse für ein solches Szenario. Jeder Thread, sowohl das Schreiben als auch das Lesen von Threads, muss alle Zugriffe auf die Liste in LockList und UnlockList Paare einwickeln.

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; 

Wenn Sie eine Delphi verwenden, die Generika gibt es eine generische Version, TThreadList<T> unterstützt.

+0

hmm. das kam mir nie in den Sinn, ich dachte, es wäre sicher, wenn nur ein Thread darüber schreibt, aber nie an das Problem gedacht hat, das Sie gerade aufgeklärt haben. also sollte ich dann eine threadlist verwenden. Danke –

+0

Ich werde Indys TIdThreadSafeList verwenden, ich habe nur versucht, die Idee des Sperren und Entsperren irgendwie zu überspringen. Es gibt so viele Threadsafelisten auf dem Server und Sperren jeder für eine Operation, die wahrscheinlich zu oft passieren wird nur zu zeitaufwendig. –

+0

Dies kann zu vielen Konflikten führen, da jeweils nur ein Thread auf die Liste zugreifen kann. Abhängig vom Typ der in der Liste gespeicherten Daten, und wenn der Schreiber keine Elemente löscht, besteht ein guter Optimierungskandidat darin, den Leser zu codieren, um die Liste zu sperren, nur um den Inhalt zu kopieren, ihn zu entsperren und dann seine Arbeit zu erledigen die Kopie. Sie können in anderen Fällen auch in einem Ansatz mit mehreren Lesern und einzelnen Schreibern denken. – jachguate

5

Wie bereits erwähnt, ist TList für sich nicht threadsicher. Wenn Sie sich Sorgen machen über den Overhead der Verwendung von TThreadList (die intern einen kritischen Abschnitt verwendet), dann sehen Sie sich an, Ihren vorhandenen Code TList mit einem TMultiReadSingleWriteSynchronizer oder sogar einem Win32 SRW lock zu verpacken.