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