欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

利用CreateEvent 实现简单的 —— 线程同步

程序员文章站 2022-04-02 22:56:58
...

—— 除夕前一天,最近大家都要注意安全哟 ~


线程同步

当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作直到该进程完成操作,其他线程才能对该内存地址进行操作,而其他线程又处于等待状态

我们将使用 CreateEvent 来创建一个内核对象,管理线程进行同步操作。

假设我们有20个苹果,那么运行原理如下图所示:
利用CreateEvent 实现简单的 —— 线程同步

大家都知道,互斥在某一时段是只执行一个线程的,但是互斥是没有序的,也就是说如果我们用互斥来实现上面的情况,可能会出现下面这种可能:
利用CreateEvent 实现简单的 —— 线程同步
这种情况是很有可能发生的。


如果我们在互斥的前提下,再加上有序,那不就可以实现我们需要的同步操作了吗 ?

代码实现

我们将用代码来实现线程的同步操作,其中大部分代码都加了注释 , 里面有些API的参数没有注释,可找度娘查阅

#include <Windows.h>		// 调用 win32的API

#include <iostream>
using namespace std;

// 创建两个事件  所获得的句柄   名字随便取
HANDLE hUa;
HANDLE mEng;

// 定义两个线程回调函数   用于测试线程同步
// 第一个线程执行函数
DWORD WINAPI ThreadFunc1(LPVOID lp)
{
    for(int i = 0; i < 10; ++i)
    {
        // 获取事件信号  
        WaitForSingleObject(hUa, INFINITE);	   // 如果没有信号,则不会浪费CPU为他分配的资源,直接执行其他的线程代码
        Sleep(500);
        cout << "---------- " << i << endl;
        
        SetEvent(mEng);    		// **另一个事件的信号,并将自己设置为无信号,这样每次只能执行一次循环
    }
    return 0;
}

// 第二个线程执行函数
DWORD WINAPI ThreadFunc2(LPVOID lp)
{
    for(int i = 0; i < 10; ++i)
    {
        // 重要的事情再说一次
        // 获取事件信号
        WaitForSingleObject(mEng, INFINITE);     // 如果没有信号,则不会浪费CPU为他分配的资源,直接执行其他的线程代码
        Sleep(500);
        cout << "++++++++++ " << i << endl;
        SetEvent(hUa);	 // **另一事件的信号,并将自己设置为无信号,这样每次只能执行一次循环
    }
    return 0;
}

int main()
{
    // 创建两个事件
    /*
        这里说一下这个API 的第三个参数:
        1. TRUE -->  有信号
        2. FALSE --> 无信号
        这样一开始只能执行第一个线程的代码,第二个线程等待信号方可执行
    */
    hUa = CreateEvent(NULL, FALSE, TRUE, NULL);
    mEng = CreateEvent(NULL, FALSE, FALSE, NULL);

    // 创建两个线程
    HANDLE hd[2];	
    hd[0] = CreateThread(NULL, 0, ThreadFunc1, NULL, 0, NULL);
    hd[1] = CreateThread(NULL, 0, ThreadFunc2, NULL, 0, NULL);
    
    // 等待两个创建的线程结束,否则main里执行的线程很快就结束了,防止程序一闪而过
    WaitForMultipleObjects(2, hd, TRUE, INFINITE);

    // 关闭一些句柄
    CloseHandle(hUa);
    CloseHandle(mEng);
    CloseHandle(hd[0]);
    CloseHandle(hd[1]);
    
    return 0;
}

运行效果如下:

---------- 0
++++++++++ 0
---------- 1
++++++++++ 1
---------- 2
++++++++++ 2
---------- 3
++++++++++ 3
---------- 4
++++++++++ 4
---------- 5
++++++++++ 5
---------- 6
++++++++++ 6
---------- 7
++++++++++ 7
---------- 8
++++++++++ 8
---------- 9
++++++++++ 9

新的一年,愿各位开心生活每一天,虽然感觉特别难……

^ _ ^

相关标签: Win32学习