Windwos下的互斥锁,事件以及事件的手动重置和自动重置的区别

事件的自动重置:两个线层同时访问一个函数,该函数会对全局变量进行操作,用事件进行互斥,假设这个事件初始化有信号   在经过WAITFORSIGALOBJECT()后事件就会变为没有信号,另外一个线程无法进去,第一个线程操作完需设置为有信号  setEvent(events);使事件变成有信号后,第二个线程才能进入。

事件的手动重置:相当于一个用户(线层)经过WaitForSingleObject()之后 不会使事件变为无信号,所有线层都可以进去,需要ResetEvent()使事件没有信号,下面例子使用手动重置没有意义。

互斥锁Mutex:第一个线程进入原子操作后(也就是经过waitforsingleobject()函数后) 自动锁上  然后需要ReleaseMutex(mutex);第二个线程才能进去  事件相对互斥锁可以更加细腻的控制线程   

#include "iostream"
#include "windows.h"
using namespace  std;

int g_iticket = 100;
unsigned long _stdcall bar(void*pramater);
//HANDLE Mutex = nullptr; //互斥锁
HANDLE hevent = nullptr;

int main(void)
{
    int inum1 = 1;
    int inum2 = 2;
    HANDLE thread1 = CreateThread(nullptr/*安全描述符*/, 0/*建立的线程空间的大小-默认大小*/, bar/*线程函数*/, &inum1, 0/*马上开始运行*/, nullptr/"线程的名字"/);
    HANDLE thread2 = CreateThread(nullptr, 0, bar, &inum2, 0, nullptr);
  //HANDLE Mutex = CreateMutex(nullptr/*安全默认权限*/, false/*创建者是否为锁的拥有者*/, nullptr/*名字*/);
    
    hevent = CreateEvent(nullptr, false/*是否手动重置*/, true/*有没有信号,有信号才能进门*/
                        , nullptr);//手动重置在waiforobjecket()后不会关门需要在后面加reset(event)

 // hevent = CreateEvent(nullptr, false, false, nullptr);//否手动重置,初始无信号,匿名
 // SetEvent(hevent); //由于初始没信号 给他一个信号

  // hevent = CreateEvent(nullptr, true, true, nullptr);//是 手动重置,初始没有信号,匿名


    if (thread1)
    {
        CloseHandle(thread1);
    }
    if (thread1)
    {
        CloseHandle(thread2);
    }
    Sleep(8000);
    CloseHandle(hevent);
    return 0;
}

unsigned long _stdcall bar(void*pramater)
{
    int* inum = reinterpret_cast<int *>(pramater);
    while (true)
    {       
        WaitForSingleObject(Mutex ,INFINITE)
        WaitForSingleObject(hevent, INFINITE);//等待一个人线程得到锁,得到后另一个线程阻塞在这里  进去过后就没信号
        //ResetEvent(hevent);用于手动重置     //自动重置的话需要加:票0回出现~~  应为设为自动重置的话用户经过waitforSigleObject()不会置事件无信号,所有线层都可进去
        if (g_iticket > 0)
        {
            Sleep(50);
            cout << "#" <<*inum<<":" <<g_iticket-- << endl;
            //ReleaseMutex(Mutex);//第一个线程执行完过后释放这个锁好让第二个线程进入
            SetEvent(hevent);
            
        }
        else
        {
            //ReleaseMutex(Mutex);
            SetEvent(hevent);
            break;
        }
        
    }
    return 0;

    
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章