c/c++中双进程守护的示例分析-创新互联

小编给大家分享一下c/c++中双进程守护的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

为娄星等地区用户提供了全套网页设计制作服务,及娄星网站建设行业解决方案。主营业务为成都做网站、成都网站建设、娄星网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

科普:
大学自学操作系统的时候不懂,慢慢的也就懂了。穿孔器、纸卡带的年代只有程序,为了解决人与CPU的交互效率低下,单批道处理器当年就出现了。但是仍然满足不了需求,这时候多批道处理也就成了时间产物(从晶体管到小规模集成电路到3D晶体管技术)。进程(PCB进程控制块),也是为了解决多批道处理下程序不可控,结果不可复用(资源共享带来的双刃剑)问题才真正的被运用起来。然而分时系统、实时系统精准程度要求,高并发的需求等,线程也才真正的立足于系统,成为最小的调度执行单位。
而原子操作、临界区、互斥体这些东西都要基于多线程来说,线程同步、异步同步。也就有了消费者与生产者,哲学家等同步问题。简单理解为保证数据不混乱、有层次有逻辑的去相互配合执行任务。有紧急任务(高优先级)可以抢占处理机,而且具有公平性,每个进程都有机会被运行;有较大的吞吐量,所有要有合理的调度算法。

原子操作:
简单来说,保证利用某一资源时候,当前资源不被其他CPU抢占使用。
缺点:只能解决某一个变量,比如是一个变量数据做简单运算(有相对的原子操作API)。
临界区:
基于原子操作的缺点,临界区概念慢慢形成。临界区可以保护一段代码指令。
由InitializeCriticalSection(..)初始化一个临界区,谁初始化的这个临界区就属于谁,有拥有者的概念。
拥有者无限调用EnterCriticalSection()则不会被阻塞,其他的则会被阻塞在外,直到DeleteCriricalSection()销毁  ,临界区由InitializeCriticalSection ------>  LeaveCriticalSection形成了保护。
互斥体:
临界区啥缺点?他不是内核对象?什么是内核对象,我们可以把进程、线程、文件IO、互斥体、信号量、事件、线程池、访问令牌、计时器等都叫做内核对象,可以参考《windows核心编程》一书。
既然是内核对象?当然可以跨进程、临界区是无法做到这一点,互斥体也有类似于临界区拥有则的概念,重要的是有两种状态:1、激发态  2、非激发态。来判断当前互斥体是否被使用,而且如果互斥体内部进程或者线程崩溃,那么互斥体空间将自动释放且为激发态,但是他只能被拥者去则释放,不可以被别的线程释放
创建一个互斥体CreateMutex(),一般互斥体用于写单实例进程,因为互斥体(参数3)是系统全局唯一,可以判断当前系统是否已存在该进程,如果存在则不再打开或则创建。
OpenMutexW()打开一个互斥体
ReleaseMutex释放存在的互斥体。

利用互斥体实现单一进程检测源码如下:

#include 
#include 
#include 

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++中双进程守护的示例分析

以上是“c/c++中双进程守护的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联行业资讯频道!

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


当前题目:c/c++中双进程守护的示例分析-创新互联
文章源于:http://myzitong.com/article/pgeji.html