【问题标题】:Object synchronization with using ThreadPool使用 ThreadPool 进行对象同步
【发布时间】:2010-02-05 14:49:54
【问题描述】:

我有多个与 ThreadPool 一起使用的处理器对象,以便在并行进程中使用它们。我将使用哪种处理器基本上取决于传入的数据,可能有超过 2000 种不同的类型;因此,一旦我的应用程序运行,它就会在字典中创建 1-2K 数量的处理器,并根据 ThreadPool 中的传入数据运行我需要的处理器。顺便说一句,任何过程都不会超过一毫秒。

我在线程池中运行的伪代码如下:

public void onIncomingNewData(rawData)
{
     if (!ThreadPool.QueueUserWorkItem(processors[rawData.Type.Id].Process, rawData))
     {
         Console.WriteLine("Work item cannot be queued!");
      }

      //Thread.Sleep(1);
}

我的问题是同步处理器对象;他们有自己的内部缓存,我不希望多个线程运行相同的 Process 对象处理方法。

目前我在处理方法和处理方法调用的其他一些私有方法中使用“锁定”。但是最好的方法是什么?

【问题讨论】:

  • 取决于“同步”的含义。这种同步的目标是什么?

标签: c# multithreading parallel-processing threadpool


【解决方案1】:

您基本上需要的是基于类型的处理器池。与其在处理器字典中缓存一个实际的处理器,不如创建一个跟踪可用和活动处理器的池类。当一个请求进来时,找到合适的池。然后查看是否有可用的处理器。如果是这样,请将其从可用列表中取出并放入活动列表中。运行 Process 方法,然后将其从活动列表中取出并放入可用列表中。

您可以不使用活动/可用列表而只使用活动标志。根据并发进程的数量,这可能会更有效。

但是,如果每个 Process 调用只需要一毫秒,那么对于您的特定需求来说,这听起来有点过分了。我建议使用 lock() 进行同步并添加一些日志以查看进程等待锁的频率。如果在测试中你发现它是一个问题,那就继续做一些更复杂的事情。

您可能还需要锁定对processors 字典的访问,除非它已经是线程安全的。如果字典是 100% 预加载的,则可能没有必要。

【讨论】:

  • 同意——这听起来很像 Reed Copsey 最近在博客中提到的一个问题(reedcopsey.com/2009/11/12/…)。他的回答是使用 .NET 4.0 中可用的实例级线程本地存储。如果您还没有使用 4.0,那么池可能是最好的解决方案。正如 Reed 发现的那样,锁定共享进程数据可能会抵消通过并行化获得的性能提升,尤其是对于此类快速操作。
【解决方案2】:

不是将处理器方法注入线程池,而是让每个处理器维护自己的请求队列并将自己的工作方法注入线程池。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多