2012-06-14 30 views
3

我正在研究一個涉及兩個過程的項目,讓他們成爲A和B. A有兩個線程:T1和T2。有什麼辦法可以將崩潰進程同步到進程中?

A和B分別運行。

在某個時刻T1向B發送一條消息(這是一個COM調用,一個搜索請求)給B。當B處理了一些數據後,它通過直接發送結果(再次,它是一個COM調用,搜索結果)返回到T2。 我需要T1阻塞,直到T2處理了B的數據。 到目前爲止,我用以下解決方案:

初始化: searchSyncSempahore = ::CreateSemaphore(NULL, 0, 1, NULL);

T1:

B_handle->search(searchString); 
::WaitForSingleObject(searchSyncSempahore, INFINITE); 
// Use searchResult variable 

T2:

searchResult = _some_data_from_B; 
::ReleaseSemaphore(searchSyncSempahore, 1, NULL); 

到目前爲止是這種情況。即使B速度如此之快以至T2在WaitForSingleObject行到達之前調用ReleaseSemaphore,它也能工作。

我的問題是:如果B崩潰會發生什麼? T1將永遠等待。我必須指定超時時間,但是如果T2收到結果時它太低,它會把信號量搞亂,搞亂下面的搜索。

那麼我怎麼能正確地同步這兩個線程考慮到永遠不會被調用的T2(即如何實現「中止搜索」)?

+0

這真的很複雜。既然你總是等待結果,爲什麼不在T1中使用同步調用,並在調用完成時將結果傳遞給T2呢?讓COM照顧家務。 – arx

+0

我無法訪問B代碼,所以我無法修改它。 B的設計就是這樣的:它公開了一個異步接口並使用調度接口進行回調。 'T2'實際上是ATL Sink線程。 – Emiliano

回答

3

可能的解決方案是創建一個看門狗線程將使用Manual-Reset events處理這種情況。所以邏輯將會改變一個小點:不要等待互斥量,你可以等待事件。看門狗線程比可以檢查線程是否長時間滯留,只是自行設置事件,並可以設置額外的事件說明出現危急情況。 我的意思是這第三個線程可以作爲看門狗定時器

另一種變型是在第三個線程中使用Condition Variables。所以,你可以簡單地踢一個條件變量,它會喚醒等待它的線程。我必須承認,我對這種方法不是很熟悉。

UPDATE: 考慮使用SignalObjectAndWait函數。該函數發信號通知一個對象,並作爲單個操作等待另一個對象。此外,您可以設置等待超時,並且如果時間間隔過去,函數將返回,即使對象的狀態爲非信號。

使用線程監視程序的另一個好處是,您可以在其中執行其他操作:記錄到文件或甚至在MS EventLog中,或者可以提供邏輯來更改應用程序行爲。又一個例子是看門狗線程可以實現'線程冗餘'功能。

+0

嗯,這可以解決問題。看門狗線程也可以設置一個標誌,以便如果T2是「遲到」(即設置標誌),它可以返回而不釋放信號量。我需要一個互斥體來保護國旗,我猜 – Emiliano

+0

沒錯。這個想法是給看門狗線程一個控制線程工作流程的機會。如果以類比RTOS系統(準確地說是ThreadX),看門狗線程創建並管理事件標誌組(例如32位數字),其中每一位表示特定共享的狀態(繁忙或空閒)資源。孩子們的線程只是等待不同的位(在我們的例子中是事件)。 – gahcep

2

比明確的看門狗更簡單的方法可能是等待進程句柄。 Windows等待函數可以等待幾乎所有作爲一種句柄(文件,套接字,線程,進程,事件......)的所有東西。

因此,使用WaitForMultipleObjects並把你的信號量和一個進程句柄(或主線程句柄)放入等待集。如果信號量發出信號或進程終止(無論出於何種原因),則等待函數應該相應地返回。

您可以區分哪個對象導致等待函數從返回值返回(應爲WAIT_OBJECT_0WAIT_OBJECT_0 + 1)。如果崩潰已經發生之前您調用了等待函數,則句柄無效,那麼等待函數應該返回WAIT_FAILED,這是應該檢查的另一個條件。

+0

+1是的,很好的解決方案。可以調用'GetCurrentThreadId'來檢索線程句柄。 – gahcep

相關問題