【问题标题】:Delphi TList in multithreading多线程中的Delphi TList
【发布时间】:2013-01-20 15:08:50
【问题描述】:

在所有其他线程都可以访问但只有一个线程写入的多线程应用程序中使用 TList 是否安全。场景是

每个线程都有一个唯一的 TList,只有该线程会写入,而其他线程只会访问它以从中获取数据。

安全吗?

【问题讨论】:

    标签: multithreading delphi tlist


    【解决方案1】:

    没有同步是不安全的。读取线程可以在写入线程修改列表的同时处于读取的中间。修改列表可能意味着重新分配底层内存。

    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>

    【讨论】:

    • 嗯。我从来没有想到过,我认为如果只有一个线程写入它会很安全,但从没想过你刚刚解决的问题。所以我应该使用 tthreadlist 。谢谢
    • 我将使用 indy 的 TIdThreadSafeList,我只是想以某种方式跳过锁定和解锁的想法。服务器中有很多线程安全列表,并为可能发生太多次的操作锁定每个线程安全列表,感觉太耗时了。
    • 这可能会引起很多争用,因为在任何给定时间只有一个线程可以访问该列表。根据存储在列表中的数据类型,如果作者不删除项目,一个好的优化候选者是编写阅读器锁定列表,只是为了复制内容,解锁它然后执行它的工作副本。在其他情况下,您还可以考虑采用多读者单作者的方法。
    • 是的,这就是我认为我应该做的,我锁定列表将其分配给一个简单的 tlist 解锁线程安全列表,然后在正常的 tlist 上执行操作。
    • 如果写线程破坏了项目并且你复制了引用,那将不起作用
    【解决方案2】:

    正如其他人所说,TList 本身不是线程安全的。如果您担心使用TThreadList(在内部使用临界区)的开销,那么看看用TMultiReadSingleWriteSynchronizer 甚至是Win32 SRW lock 包装您现有的TList 代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      • 1970-01-01
      • 1970-01-01
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      • 2021-09-29
      相关资源
      最近更新 更多