溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

c/c++中雙進(jìn)程守護(hù)的示例分析

發(fā)布時(shí)間:2022-01-15 14:13:05 來(lái)源:億速云 閱讀:219 作者:小新 欄目:編程語(yǔ)言

小編給大家分享一下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ù)的示例分析

以上是“c/c++中雙進(jìn)程守護(hù)的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI