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;

    
}

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