2010-02-05 41 views
1

我有多個處理器對象,我使用ThreadPool在並行進程中使用它們。我要使用哪個處理器基本上取決於傳入的數據,並且可能有超過2000種不同的類型;所以只要我的應用程序運行,它會在字典中創建1-2K個處理器,並根據ThreadPool中的傳入數據運行我需要的處理器。任何進程不會超過一毫秒btw。使用ThreadPool進行對象同步

我在線程池運行的僞代碼如下:

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

     //Thread.Sleep(1); 
} 

我的問題這裏synchrnozing之處理對象;他們有他們的內部緩存,我不希望多個線程運行相同的過程對象處理方法。

此刻,我正在使用「鎖定」進程方法和一些其他處理方法調用的私有方法。但是,最好的方法是什麼?

+0

取決於你的意思是「同步」。這種同步的目標是什麼? – Will 2010-02-05 15:02:29

回答

1

你基本上需要的是一個基於類型的處理器池。不是在處理器字典中緩存實際處理器,而是創建一個跟蹤可用和活動處理器的池類。當請求進入時,找到合適的池。然後看看是否有任何可用的處理器。如果是,請將其從可用列表中取出並放入活動列表中。運行Process方法,然後將其從活動列表中取出並放入可用列表中。

你可以逃避不使用活動/可用列表,而只是使用活動標誌。根據併發進程的數量,這可能更有效。

但是,如果每個進程調用只需要一毫秒,那麼這聽起來像是針對您的特定需求的矯枉過正。我建議使用lock()進行同步,並添加一些日誌記錄來查看進程等待鎖定的頻率。如果在測試中發現它是一個問題,那麼繼續處理更復雜的問題。

您也可能需要鎖定對processors字典的訪問,除非它已經是線程安全的。如果字典是100%預加載的,則可能不需要。

+0

同意 - 這聽起來很像一個問題裏德科普塞最近博客(在http://reedcopsey.com/2009/11/12/thread-specific-data-becomes-easier-in-net-4-0-via -threadlocalt /)。他的回答是使用.NET 4.0中提供的實例級線程本地存儲。如果你還沒有使用4.0,一個池可能是最好的解決方案。正如Reed發現的,鎖定共享進程數據可以消除並行化所帶來的性能收益,特別是對於這種快速操作。 – 2010-02-05 15:12:46

0

取而代之的是向線程池中注入處理器方法,而不是讓每個處理器維護自己的請求隊列,並將自己的工作者方法注入到線程池中。