2010-11-09 41 views
3

我想在win32環境中使用事件對象來同步兩個進程。以下是兩個程序的簡化代碼。在進程間使用事件對象

// process1 
int main() 
{ 
    HANDLE h = CreateEvent(NULL, FALSE, FALSE, TEXT("Hello")); 
    WaitForSingleObject(h, INFINITE); 
// RunProcess(L"process2.exe", L""); 
} 

// process2 
int main() 
{ 
    HANDLE h = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("Hello")); 
    SetEvent(h);  
} 

這很簡單,並且在兩個進程獨立啓動時運行良好。但是,當進程1啓動進程2作爲子進程(在上面的代碼中進行了註釋)時,SetEvent調用失敗時不起作用。這個問題的原因和解決方法是什麼?

回答

3

您的代碼需要檢查並處理錯誤。如果它們失敗,CreateEventOpenEvent將返回NULL,在這種情況下,您需要使用GetLastError檢查錯誤。

您應該檢查每個MSDN文檔WaitForSingleObjectSetEvent

中,你需要做的事情在父進程的順序是:

  • CreateEvent
  • 啓動子進程
  • WaitForSingleObject的。

否則,您會遇到@Mark Tolonen提出的問題。

最好還是等待一段時間,以處理子進程無法啓動,意外退出或掛起的情況。

如果您打算使用此父/子關係,另一種方法是允許繼承事件句柄。然後,該事件不需要命名,並且在應用程序的DoS攻擊中沒有其他人可以「蹲坐」它。您可以將句柄值作爲命令行參數傳遞給孩子。您可以使用eventAttributes參數中的bInheritHandle字段對CreateEvent執行此操作。

一個布爾值,指定 時創建 一個新的進程返回的句柄是繼承。如果這個 成員爲TRUE,則新進程 將繼承該句柄。

+0

感謝您的詳細解答!神奇地解決了這個問題 - 它今天終於有效,沒有修改代碼。 :(雖然我覺得我應該寫一些異常處理代碼,並且你幫了我很多。 – summerlight 2010-11-10 01:40:21

1

你確定嗎?正如所寫的,如果process1在當前位置創建process2,它將永遠不會創建process2,因爲它將永遠等待事件被觸發。首先創建process2,然後等待事件被設置。

+1

啊,這是我的錯誤 - 原始代碼更復雜,我在簡化代碼時犯了一個錯誤。 :(如上所述,註釋代碼應該移到WaitForSingleObject的上方 – summerlight 2010-11-10 01:35:30

+0

只要問題保持不變,這個答案很簡單:-) – Wolf 2015-11-20 12:15:13

2

你有一個NULL安全描述符,該文件說,不能讓手柄兒童進程繼承,具體有:

If this parameter is NULL, the handle cannot be inherited by child processes

也許你需要創建一個適當的安全描述符?