2011-04-03 45 views
0

我在空閒時間寫了一個圖像板刮板來教我主要關於線程。目前我正在使用生產者/消費者類型模式來促進這項工作。但是,我遇到了一個問題。跟蹤不同線程上對象實例的狀態?

現在,我有「隊列處理器」,觀察並處理特定類型的線程安全隊列。這些隊列處理器每隔X秒輪詢一次目標隊列,並且如果隊列中有等待處理的項目,隊列處理器會使該項目出隊,使用該項目旋轉一個新線程並啓動線程。在每個線程上,調用長時間運行的方法(如連接到網站並下載文件)。以這種方式,每個項目都有自己的線程運行。

我很難搞清楚如何報告每個線程正在處理的每個項目的狀態。

例如,假設我們有主線程MT。 MT產生子線程T1,T2,T3,T4和T5。在每個線程上都有一個對應的對象,O1 ... O5。這些對象可以處於三種不同的狀態(S1,S2,S3),而它們正在其線程上進行處理。

如何在對象O的狀態發生變化時向主線程MT報告每個對象O的狀態S?

我嘗試使用事件來報告狀態,但我遇到了一些令人毛骨悚然的結果。我搜索了一些關於使用線程和事件的信息,但沒有得到太多的結果。

任何幫助,將不勝感激。

謝謝。

回答

1

一種方法是創建另一個線程安全隊列,用於報告狀態更新。每當你的線程改變它的狀態時,它都會推送一個元組/對象,它包含作業的唯一標識符,新狀態,線程標識以及你認爲需要的任何其他內容。

一旦你這樣做了,你會遇到另一個問題:誰來輪詢隊列?你可以在你的主線程在它對工作隊列的檢查之間做到這一點,但這可能很難看,並且可能會不必要地減慢處理速度。你也可以爲此做出另一個線程,但我猜你需要將狀態報告給主線程,所以這沒有幫助。

實際上有更好的方法來構造程序。不是讓主線程連續輪詢作業隊列並創建線程(這非常昂貴),而是可以創建一個線程池並讓作業線程自己執行輪詢。這將使主線程免費輪詢狀態隊列,等待它正在查找的任何事件。

下面是一些僞代碼來說明這一概念:

main_thread() 
    ... 
    thread_pool = create_pool(get_core_count()); 
    thread_pool.execute(worker_thread); 

    while(true) 
     status = status_queue.pop_blocking(); 
     if (check_status(status) == WE_BE_DONE) 
      break; 

    thread_pool.interrupt(); 
    ... 

worker_thread() 
    while(true) 
     job = job_queue.pop_blocking(); 
     process_job(job); 
     status_queue.push({job.id, thread_id, WE_DONE}); 

從本質上講,這是什麼做的是創建一個包含每個你有CPU核心一個工作線程(一個確定的默認開始)線程池。接下來,它在每個工作線程中執行函數worker_thread(該函數應該是不言自明的)。主線程然後不斷地檢查狀態隊列以查找某個未指定的事件。一旦發生這種情況,它會關閉工作線程並繼續執行程序的其餘部分。

這個例子值得注意的三件事。首先,我建議在手動輪詢實施中使用屏蔽流行呼叫(示例中爲pop_blocking)。使用起來要簡單很多,效率可能更高。接下來,我使用thread_pool.interrupt()來終止工作線程,但根據您使用的語言或庫,它可能不是最聰明的方法。如果您的語言支持這種事情,那麼在try catch聲明中圍繞do_job(job)調用可能也是一個好主意。

請注意,由於您的問題對於細節(語言被用於某個細節)非常不利,因此您肯定需要將解決方案適應於您正在嘗試完成的任何操作。這應該仍然給你一個很好的起點。