美文网首页
windows内核对象

windows内核对象

作者: MagicalGuy | 来源:发表于2018-10-07 14:29 被阅读0次

    临界区

    include "stdafx.h"

    include <windows.h>

    CRITICAL_SECTION cs = {};

    int g_nNum = 0;
    DWORD WINAPI ThreadProc(LPVOID lParam) {
    // 2. 进入临界区
    // cs有个属性LockSemaphore是不是被锁定
    // 当调用EnterCriticalSection表示临界区被锁定,OwningThread就是该线程
    // 其他调用EnterCriticalSection,会检查和锁定时的线程是否是同一个线程
    // 如果不是,调用Enter的线程就阻塞
    // 如果是,就把锁定计数LockCount+1
    // 有几次Enter就得有几次Leave
    // 但是,不是拥有者线程的人不能主动Leave
    EnterCriticalSection(&cs);
    for (int i = 0; i < 100000; i++)
    {
    g_nNum++;
    }
    printf("%d\n", g_nNum);
    // 3. 离开临界区
    // 万一,还没有调用Leave,该线程就崩溃了,或死循环了..
    // 外面等待的人就永远等待
    // 临界区不是内核对象, 不能跨进程同步
    LeaveCriticalSection(&cs);
    return 0;
    }

    int main()
    {
    // 1. 初始化临界区
    InitializeCriticalSection(&cs);
    HANDLE hThread1 = CreateThread(NULL, NULL, ThreadProc, NULL, NULL, NULL);
    HANDLE hThread2 = CreateThread(NULL, NULL, ThreadProc, NULL, NULL, NULL);
    WaitForSingleObject(hThread1, INFINITE);
    WaitForSingleObject(hThread2, INFINITE);
    printf("%d\n", g_nNum);
    // 4. 销毁临界区
    DeleteCriticalSection(&cs);
    return 0;
    }

    ==================
    互斥体

    include "stdafx.h"

    include <windows.h>

    HANDLE hMutex = 0;
    int g_nNum = 0;
    // 临界区和互斥体比较
    // 1. 互斥体是个内核对象,可以跨进程同步,临界区不行
    // 2. 当他们的拥有者线程都崩溃的时候,互斥体可以被系统释放,变为有信号,其他的等待函数可以正常返回
    // 临界区不行,如果都是假死(死循环,无响应),他们都会死锁
    // 3. 临界区不是内核对象,所以访问速度比互斥体快
    DWORD WINAPI ThreadProc(LPVOID lParam) {
    // 等待某个内核对象,有信号就返回,无信号就一直等待
    // 返回时把等待的对象变为无信号状态
    WaitForSingleObject(hMutex, INFINITE);
    for (int i = 0; i < 100000; i++)
    {
    g_nNum++;
    }
    printf("%d\n", g_nNum);
    // 把互斥体变为有信号状态
    ReleaseMutex(hMutex);
    return 0;
    }

    int main()
    {
    // 1. 创建一个互斥体
    hMutex = CreateMutex(
    NULL,
    FALSE,// 是否创建时就被当先线程拥有
    NULL);// 互斥体名称
    HANDLE hThread1 = CreateThread(NULL, NULL, ThreadProc, NULL, NULL, NULL);
    HANDLE hThread2 = CreateThread(NULL, NULL, ThreadProc, NULL, NULL, NULL);
    WaitForSingleObject(hThread1, INFINITE);
    WaitForSingleObject(hThread2, INFINITE);
    printf("%d\n", g_nNum);
    return 0;
    }

    =====================
    防多开

    include "stdafx.h"

    include <windows.h>

    int main()
    {
    if (OpenMutex(SYNCHRONIZE, NULL, L"24期"))
    {
    // 说明互斥体存在,已经打开过一次程序
    return 0;
    }
    HANDLE hMutex = CreateMutex(NULL, NULL, L"24期");
    system("pause");
    return 0;
    }

    ===================
    信号量

    include "stdafx.h"

    include <windows.h>

    HANDLE hSemphore;
    int g_nNum = 0;
    DWORD WINAPI ThreadProc(LPVOID lParam) {
    WaitForSingleObject(hSemphore, INFINITE);
    for (int i = 0; i < 100000; i++)
    {
    g_nNum++;
    }
    printf("%d\n", g_nNum);
    ReleaseSemaphore(hSemphore,
    1,// 释放的信号个数可以大于1,但是释放后的信号个数+之前的不能大于最大值,否则释放失败
    NULL);
    return 0;
    }

    int main()
    {
    hSemphore = CreateSemaphore(
    NULL,
    1,// 初始信号个数
    1,// 最大信号个数,就是允许同时访问保护资源的线程数
    NULL);
    HANDLE hThread1 = CreateThread(NULL, NULL, ThreadProc, NULL, NULL, NULL);
    HANDLE hThread2 = CreateThread(NULL, NULL, ThreadProc, NULL, NULL, NULL);
    WaitForSingleObject(hThread1, INFINITE);
    WaitForSingleObject(hThread2, INFINITE);
    printf("%d\n", g_nNum);
    return 0;
    }
    =========================
    事件

    include "stdafx.h"

    include <windows.h>

    HANDLE hEvent1, hEvent2;
    DWORD WINAPI ThreadProcA(LPVOID lParam) {
    for (int i = 0; i < 10; i++){
    WaitForSingleObject(hEvent1, INFINITE);
    printf("A ");
    SetEvent(hEvent2);
    }
    return 0;
    }

    DWORD WINAPI ThreadProcB(LPVOID lParam) {
    for (int i = 0; i < 10; i++){
    WaitForSingleObject(hEvent2, INFINITE);
    printf("B ");
    SetEvent(hEvent1);
    }
    return 0;
    }

    int main()
    {
    // 事件对象,高度自定义的
    hEvent1 = CreateEvent(
    NULL,
    FALSE,// 自动重置
    TRUE,// 有信号
    NULL);
    // hEvent1自动重置 初始有信号 任何人通过setevent变为有信号 resetevent变为无信号
    // hEvent2自动重置 初始无信号
    hEvent2 = CreateEvent(NULL, FALSE, FALSE, NULL);
    HANDLE hThread1 = CreateThread(NULL, NULL, ThreadProcA, NULL, NULL, NULL);
    HANDLE hThread2 = CreateThread(NULL, NULL, ThreadProcB, NULL, NULL, NULL);
    WaitForSingleObject(hThread1, INFINITE);
    WaitForSingleObject(hThread2, INFINITE);
    return 0;
    }

    =================
    双进程守护

    include "stdafx.h"

    include <windows.h>

    int main()
    {
    HANDLE hEventA = CreateEvent(NULL, FALSE, TRUE, L"我是A");
    HANDLE hEventB = NULL;
    printf("我是A\n");
    while (true)
    {
    hEventB = OpenEvent(SYNCHRONIZE, NULL, L"我是B");
    if (!hEventB)
    {
    STARTUPINFO si = {};
    PROCESS_INFORMATION pi = {};
    if (!CreateProcess(L"..\Debug\06.双进程守护B.exe",
    NULL, NULL, NULL, NULL, CREATE_NEW_CONSOLE, NULL,
    NULL, &si, &pi))
    return 0;
    WaitForSingleObject(pi.hProcess, INFINITE);
    Sleep(100);
    }
    else
    {
    CloseHandle(hEventB);
    Sleep(200);
    }
    }
    return 0;
    }

    include "stdafx.h"

    include <windows.h>

    int main()
    {
    HANDLE hEventB = CreateEvent(NULL, FALSE, TRUE, L"我是B");
    HANDLE hEventA = NULL;
    printf("我是B\n");
    while (true)
    {
    hEventA = OpenEvent(SYNCHRONIZE, NULL, L"我是A");
    if (!hEventA)
    {
    STARTUPINFO si = {};
    PROCESS_INFORMATION pi = {};
    if (!CreateProcess(L"..\Debug\05.双进程守护A.exe",
    NULL, NULL, NULL, NULL, CREATE_NEW_CONSOLE, NULL,
    NULL, &si, &pi))
    return 0;
    WaitForSingleObject(pi.hProcess, INFINITE);
    //Sleep(100);
    }
    else
    {
    CloseHandle(hEventA);
    }
    }
    return 0;
    }

    相关文章

      网友评论

          本文标题:windows内核对象

          本文链接:https://www.haomeiwen.com/subject/rjblaftx.html