Test the efficiency of the exclusion objects in Windows

There are mainly four kinds of exclusion objects, which can be used in solving the problems of race condition, on Windows platform. They are Critical Section, Mutex, Semaphore, and Event. As most people know, Critical Section is the fastest way to achieve mutual exclusion, while the other three have the same efficiency more or less. The reason is that Critical Section is not a kernel object. It is only a local object within some process. Using it will not cause the switch of the executing mode from user mode to kernel mode. So it saves a lot of time. But the biggest weakness followed is that Critical Section can only be used in a single process, i.e., any of the threads in that same process can access it, while other threads or processes cannot.

The following code tests the efficiency of the four exclusion objects in Windows OS. The IDE is Visual Studio 2008 Team Suite, with DotNet Framework 3.5.

//Exclusion.h

#ifndef _EXCLUSION_H_
#define  _EXCLUSION_H_

#include 
< windows.h >
#include 
< cassert >
#include 
< cstdlib >
#include 
< iostream >
using   namespace  std;

class  Exclusion  {
public:
    
virtual void Initialize() = 0;
    
virtual void Destroy() = 0;
    
virtual void Lock() = 0;
    
virtual void Unlock() = 0;
}
;

class  CriticalSectionExclusion :  public  Exclusion  {
private:
    CRITICAL_SECTION _cs;
public:
    CriticalSectionExclusion() 
{}
    
void Initialize() { InitializeCriticalSection(&_cs); }
    
void Destroy() { DeleteCriticalSection(&_cs); }
    
void Lock() { EnterCriticalSection(&_cs); }
    
void Unlock() { LeaveCriticalSection(&_cs); }
    
bool TryLock() return (TryEnterCriticalSection(&_cs) == TRUE) ? true : false; }
}
;

class  MutexExclusion :  public  Exclusion  {
private:
    HANDLE _mutex;
    LPCWSTR _name;
public:
    MutexExclusion() : _mutex(
0), _name(0{}
    MutexExclusion(LPCWSTR lpname) : _mutex(
0), _name(lpname) {}
    
void Initialize() { _mutex = CreateMutex(0, TRUE, _name); assert(_mutex != 0); }
    
void Destroy() { CloseHandle(_mutex); }
    
void Lock() if(WaitForSingleObject(_mutex, INFINITE) != WAIT_OBJECT_0) abort(); }
    
void Unlock() { ReleaseMutex(_mutex); }
}
;

class  SemaphoreExclusion :  public  Exclusion  {
private:
    HANDLE _semaphore;
    LPCWSTR _name;
public:
    SemaphoreExclusion() : _semaphore(
0), _name(0{}
    SemaphoreExclusion(LPCWSTR lpname) : _semaphore(
0), _name(lpname) {}
    
void Initialize() { _semaphore = CreateSemaphore(011, _name); assert(_semaphore != 0); }
    
void Destroy() { CloseHandle(_semaphore); }
    
void Lock() if(WaitForSingleObject(_semaphore, INFINITE) != WAIT_OBJECT_0) abort(); }
    
void Unlock() { ReleaseSemaphore(_semaphore, 10); }
}
;

class  EventExclusion :  public  Exclusion  {
private:
    HANDLE _event;
    LPCWSTR _name;
public:
    EventExclusion() : _event(
0), _name(0{}
    EventExclusion(LPCWSTR name) : _event(
0), _name(name) {}
    
void Initialize() { _event = CreateEvent(0, FALSE, TRUE, _name); assert(_event != 0); }
    
void Destroy() { CloseHandle(_event); }
    
void Lock() if(WaitForSingleObject(_event, INFINITE) != WAIT_OBJECT_0) abort(); }
    
void Unlock() { SetEvent(_event); }
}
;

#endif

//Time.h

#ifndef _TIME_H_
#define  _TIME_H_

#include 
< windows.h >

class  Time  {
public:
    
virtual void Initialize() = 0;
    
virtual void Start() = 0;
    
virtual void Stop() = 0;
    
virtual double GetOnceTime() = 0;
    
virtual double GetTotalTime() = 0;
    
virtual void Reset() = 0;
}
;

class  TickCountTime :  public  Time  {

}
;

class  QueryPerformanceTime :  public  Time  {
private:
    LARGE_INTEGER _head;
    LARGE_INTEGER _tail;
    LARGE_INTEGER _freq;
    LONGLONG _once_time;
    LONGLONG _total_time;
public:
    
void Initialize() {
        _once_time 
= _total_time = 0;
        QueryPerformanceFrequency(
&_freq);
        memset(
&_head, 0sizeof(LARGE_INTEGER));
        memset(
&_head, 0sizeof(LARGE_INTEGER));
    }

    
void Start() { QueryPerformanceCounter(&_head); }
    
void Stop() {
        QueryPerformanceCounter(
&_tail);
        _once_time 
= _tail.QuadPart - _head.QuadPart;
        _total_time 
+= _once_time;
    }

    
double GetOnceTime() return ((double)_once_time) / _freq.QuadPart; }
    
double GetTotalTime() return ((double)_total_time) / _freq.QuadPart; }
    
void Reset() {
        _once_time 
= _total_time = 0;
        memset(
&_head, 0sizeof(LARGE_INTEGER));
        memset(
&_tail, 0sizeof(LARGE_INTEGER));
    }

}
;

class  AssemblyInstructionTime :  public  Time  {

}
;

#endif

//main.cpp

#include  " Exclusion.h "
#include 
" Time.h "
#include 
< iostream >
#include 
< cstdio >
using   namespace  std;

int  main()  {
    Exclusion 
* my_ex;
    Time 
* my_tm = new QueryPerformanceTime();
    my_tm
->Initialize();
    
short flag;

    flag 
= 0;
    my_ex 
= new CriticalSectionExclusion();
    my_ex
->Initialize();
    my_tm
->Start();
    
while(++flag > 0{
        my_ex
->Lock();
        my_ex
->Unlock();
    }

    my_tm
->Stop();
    printf(
"CritialSection: %1.10lf s ", my_tm->GetTotalTime());

    flag 
= 0;
    my_tm
->Reset();
    my_ex 
= new MutexExclusion();
    my_ex
->Initialize();
    my_tm
->Start();
    
while(++flag > 0{
        my_ex
->Lock();
        my_ex
->Unlock();
    }

    my_tm
->Stop();
    printf(
"Mutex: %1.10lf s ", my_tm->GetTotalTime());

    flag 
= 0;
    my_tm
->Reset();
    my_ex 
= new SemaphoreExclusion();
    my_ex
->Initialize();
    my_tm
->Start();
    
while(++flag > 0{
        my_ex
->Lock();
        my_ex
->Unlock();
    }

    my_tm
->Stop();
    printf(
"Semaphore: %1.10lf s ", my_tm->GetTotalTime());

    flag 
= 0;
    my_tm
->Reset();
    my_ex 
= new EventExclusion();
    my_ex
->Initialize();
    my_tm
->Start();
    
while(++flag > 0{
        my_ex
->Lock();
        my_ex
->Unlock();
    }

    my_tm
->Stop();
    printf(
"Event: %1.10lf s ", my_tm->GetTotalTime());

    delete my_tm;
    
return 0;
}

The running result is shown below.

CriticalSection: 0.0050035730 s

Mutex:                 0.0473425394 s

Semaphore:      0.0465372747 s

Event:                  0.0444654282 s

The data indicates that if Critical Section is sufficient to be used in some case, never turn to the other three choices.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值