您好,登錄后才能下訂單哦!
小編給大家分享一下c/c++中雙進程守護的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
科普:
?大學自學操作系統的時候不懂,慢慢的也就懂了。穿孔器、紙卡帶的年代只有程序,為了解決人與CPU的交互效率低下,單批道處理器當年就出現了。但是仍然滿足不了需求,這時候多批道處理也就成了時間產物(從晶體管到小規模集成電路到3D晶體管技術)。進程(PCB進程控制塊),也是為了解決多批道處理下程序不可控,結果不可復用(資源共享帶來的雙刃劍)問題才真正的被運用起來。然而分時系統、實時系統精準程度要求,高并發的需求等,線程也才真正的立足于系統,成為最小的調度執行單位。
?而原子操作、臨界區、互斥體這些東西都要基于多線程來說,線程同步、異步同步。也就有了消費者與生產者,哲學家等同步問題。簡單理解為保證數據不混亂、有層次有邏輯的去相互配合執行任務。有緊急任務(高優先級)可以搶占處理機,而且具有公平性,每個進程都有機會被運行;有較大的吞吐量,所有要有合理的調度算法。
原子操作:
?簡單來說,保證利用某一資源時候,當前資源不被其他CPU搶占使用。
?缺點:只能解決某一個變量,比如是一個變量數據做簡單運算(有相對的原子操作API)。
臨界區:
?基于原子操作的缺點,臨界區概念慢慢形成。臨界區可以保護一段代碼指令。
由InitializeCriticalSection(..)初始化一個臨界區,誰初始化的這個臨界區就屬于誰,有擁有者的概念。
?擁有者無限調用EnterCriticalSection()則不會被阻塞,其他的則會被阻塞在外,直到DeleteCriricalSection()銷毀 ,臨界區由InitializeCriticalSection ------> LeaveCriticalSection形成了保護。
互斥體:
?臨界區啥缺點?他不是內核對象?什么是內核對象,我們可以把進程、線程、文件IO、互斥體、信號量、事件、線程池、訪問令牌、計時器等都叫做內核對象,可以參考《windows核心編程》一書。
?既然是內核對象?當然可以跨進程、臨界區是無法做到這一點,互斥體也有類似于臨界區擁有則的概念,重要的是有兩種狀態:1、激發態 2、非激發態。來判斷當前互斥體是否被使用,而且如果互斥體內部進程或者線程崩潰,那么互斥體空間將自動釋放且為激發態,但是他只能被擁者去則釋放,不可以被別的線程釋放。
?創建一個互斥體CreateMutex(),一般互斥體用于寫單實例進程,因為互斥體(參數3)是系統全局唯一,可以判斷當前系統是否已存在該進程,如果存在則不再打開或則創建。
OpenMutexW()打開一個互斥體
ReleaseMutex釋放存在的互斥體。
利用互斥體實現單一進程檢測源碼如下:
#include <stdio.h> #include <iostream> #include <Windows.h> using std::cout; using std::endl; BOOL IsMutex() { HANDLE hMutex = NULL; hMutex = CreateMutex(NULL, FALSE, L"TEXT"); if (hMutex) { if (ERROR_ALREADY_EXISTS == GetLastError()) { ReleaseMutex(hMutex); CloseHandle(hMutex); return TRUE; } } return FALSE; } int main(void) { if(IsMutex()) cout << "系統已存在TEXT互斥體" << endl; else cout << "第一次創建互斥體成功" << endl; system("pause"); return 0; }
信號量:
?信號量當前信號數不為0,則代表為激發態。
?注意調用WaitForSingleObject()的時候,就會把信號數-1,也就是說如果信號數不為0,那么使用該函數信號數-1,相當于又上了一把鎖,記得調用函數ReleaseSemaphore()恢復(信號數+1)。任何一個線程都可以進行釋放(互斥體成對出現),意味著多個線程可保護同一段代碼或者指令。
事件:
?這是一個相對民主的內核對象,進程同步中用的也比較多。他可以設置等待函數對于此事件對象有沒有后遺癥。而且可以手動設置激發態或者非激發態,自主性非常強,很靈活。
??1、CreateEventW()用來創建一個事件對象
??2、OPenEventA()打開一個事件對象
??3、SetEvent()設置為激發態
??4、ReSetEvent()設置為非激發態
??5、PulseEvent()手動設置激發態
??6、CloseHandle()內核對象當引用計數為0,系統管理銷毀。
?這些函數具體參數可以msdn查看或者百度看詳細信息,介紹那么多下面也要貼上一段雙進程守護代碼。
雙進程守護程序一:
int main(void) { // 創建事件對象 HANDLE hEvent = CreateEvent(NULL, FALSE, TRUE, L"守護One.exe"); while (TRUE) { HANDLE hEventTow = OpenEvent(NULL, FALSE, L"守護Two.exe"); // 如果不存在則創建 if (!hEventTow) { CreateProcess(L"守護Two.exe", NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &s_Si, &s_Pi); WaitForSingleObject(s_Pi.hProcess, INFINITE); CloseHandle(s_Pi.hThread); CloseHandle(s_Pi.hProcess); } else CloseHandle(hEventTow); } system("pause"); return 0; }
雙進程守護程序二:
STARTUPINFO s_Si = {}; PROCESS_INFORMATION s_Pi = {}; // 創建事件對象 HANDLE hEvent = CreateEvent(NULL, FALSE, TRUE, L"守護Two.exe"); while (TRUE) { HANDLE hEventTow = OpenEvent(NULL, FALSE, L"守護One.exe"); // 如果不存在則創建 if (!hEventTow) { CreateProcess(L"守護One.exe", NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &s_Si, &s_Pi); WaitForSingleObject(s_Pi.hProcess, INFINITE); CloseHandle(s_Pi.hThread); CloseHandle(s_Pi.hProcess); } else CloseHandle(hEventTow); } system("pause"); return 0;
雙進程守護缺點很多,假如我掛起其中一個進程(不被響應),另一個進程則可關閉。
?還有HOOK來保護自己,下次用一個簡單的mfc來聊一聊,fs寄存器_kpcr,還有一些Hook.
以上是“c/c++中雙進程守護的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。