2013-01-20 53 views
6

在多線程應用程序中使用TList是安全的,它可以被所有其他線程訪問,但只有一個線程寫入它。該場景是多線程中的Delphi TList

每個線程的唯一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

嗯。這從來沒有打到我的腦海裏,我認爲如果只有一個線程寫入它會是安全的,但從來沒有想到你剛纔清理的問題。所以我應該使用tthreadlist。謝謝 –

+0

我將使用indy的TIdThreadSafeList,我只是想以某種方式跳過鎖定和解鎖的想法。服務器中有許多線程安全列表,並且鎖定每一個操作可能會發生太多次的操作,只是覺得太耗時。 –

+0

這可能會導致很多爭用,因爲在任何給定的時間只有一個線程可以訪問列表。根據存儲在列表中的數據類型,如果作者不刪除項目,優秀的候選人是編碼閱讀器鎖定列表只是爲了製作內容的副本,解鎖它,然後執行它的工作副本。在其他情況下,您也可以考慮使用多讀者 - 單寫作者方法。 – jachguate

5

正如其他人所說,TList本身並不是線程安全的。如果您擔心使用TThreadList(內部使用關鍵部分)的開銷,那麼請查看使用TMultiReadSingleWriteSynchronizer甚至Win32 SRW lock將現有的TList代碼打包。