windows中可以通過Event進行跨進程的通訊, 只要在創建事件時, 事件名相同, 就會得到同一個事件的句柄, 以此為基礎可以進行跨進程通訊
先看一下msdn上的定義和解釋(下面我大概翻譯了一下, 具體內容參閱 : https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createeventa)
定義
HANDLE CreateEventA( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName );
參數
lpEventAttributes
SECURITY_ATTRIBUTES 結構體的指針. 如果此參數為NULL, 則創建的Event不能被子進程繼承.
bManualReset
該參數指明創建的Event當被激活后會不會自動復位, 如果這個參數為FALSE, 則每次事件被激活后, 需要手動調用ResetEvent來將事件復位.
bInitialState
如果該參數為TRUE, 則Event創建后的初始狀態即為激活態.
lpName
Event的名稱, 最大長度為 MAX_PATH 個字符且這個名稱是大小寫敏感的.
當要Create一個lpName已經存在的Event時,要確保程序擁有 EVENT_ALL_ACCESS 權限. 在Create已經創建了的Event時, 由於事件已經被創建, 當前函數調用中的bManualReset參數和bInitialState參數會被忽略, 與此同時, lpEventAttributes參數將只能決定這個Event能否被子進程進程, 而SECURITY_ATTRIBUTES中的安全描述符屬性會被忽略.
如果一個擁有lpName的HANDLE已經被與CreateEvent相同命名空間中的其它函數( CreateMutex等等 )創建, 再次Create相同的lpName就會導致函數失敗, 同時 GetLastError 返回 ERROR_INVALID_HANDLE. 此處還是比較容易理解的, 我們創建一把名為"張三"的鎖, 然后再創建一個名為"張三"的事件, Windows不允許這種事情發生.
如果不想讓創建的Event成為公共的, 參閱 : https://docs.microsoft.com/zh-cn/windows/win32/termserv/kernel-object-namespaces 和 https://docs.microsoft.com/zh-cn/windows/win32/sync/object-namespaces
返回值
成功返回HANDLE, 失敗返回 NULL. 可以使用 GetLastError 來檢查錯誤
下面是兩個進程間使用Event通訊的例子
激活事件進程
1 #include <iostream> 2 #include <Windows.h> 3 4 int main() 5 { 6 HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, "helloWorld"); 7 8 while (true) 9 { 10 std::cout << "set event : helloWorld" << std::endl; 11 12 SetEvent(hEvent); 13 14 Sleep(5000); 15 } 16 17 return 0; 18 }
等待事件進程
1 #include <iostream> 2 #include <Windows.h> 3 4 int main() 5 { 6 HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, "helloWorld"); 7 8 while (true) 9 { 10 WaitForSingleObject(hEvent,INFINITE); 11 12 std::cout << "helloWorld" << std::endl; 13 14 ResetEvent(hEvent); 15 } 16 17 return 0; 18 }
編譯運行后兩進程結果如下( 兩個窗口疊放在一起了, 看着有點暈 )
以上, 如有疏漏錯誤, 歡迎指正