// 互斥锁
#pragma once
#include <WinBase.h>
class MutexLock
{
public:
MutexLock()
{
InitializeCriticalSection(&criticalSection_);
}
~MutexLock()
{
DeleteCriticalSection(&criticalSection_);
}
void lock()
{
EnterCriticalSection(&criticalSection_);
}
void unlock()
{
LeaveCriticalSection(&criticalSection_);
}
CRITICAL_SECTION& cs()
{
return criticalSection_;
}
private:
MutexLock(const MutexLock&);
MutexLock& operator=(const MutexLock&);
CRITICAL_SECTION criticalSection_;
};
class MutexLockGuard
{
public:
explicit MutexLockGuard(MutexLock &mutex)
: mutex_(mutex)
{
mutex_.lock();
}
~MutexLockGuard()
{
mutex_.unlock();
}
private:
MutexLockGuard(const MutexLockGuard&);
MutexLockGuard operator=(const MutexLockGuard&);
MutexLock& mutex_;
};
// 阻塞队列
template<typename T>
class BlockQueue
{
public:
BlockQueue()
: mutex_()
, notEmpty_(mutex_)
{
}
void put(const T &t)
{
MutexLockGuard lock(mutex_);
queue_.push_back(t);
notEmpty_.notify();
}
T take()
{
MutexLockGuard lock(mutex_);
while (queue_.empty()) {
notEmpty_.wait();
}
assert(!queue_.empty());
T front(queue_.front());
queue_.pop_front();
return front;
}
size_t size() const
{
MutexLockGuard lock(mutex_);
return queue_.size();
}
private:
BlockQueue(const BlockQueue&);
BlockQueue& operator=(const BlockQueue&);
private:
mutable MutexLock mutex_;
Condition notEmpty_;
std::deque<T> queue_;
};
// 信号量
#include <deque>
#include <assert.h>
#include <Windows.h>
#include "Def.h" // for DISALLOW_COPY_AND_ASSIGN
template<typename T>
class BlockQueue
{
DISALLOW_COPY_AND_ASSIGN(BlockQueue);
public:
static const int defaultNum = 256;
BlockQueue()
: num_(defaultNum)
{
init();
}
BlockQueue(int num)
: num_(num)
{
init();
}
~BlockQueue()
{
CloseHandle(semFull_);
CloseHandle(semEmpty_);
}
void put(const T &t)
{
WaitForSingleObject(semFull_, INFINITE);
queue_.push_back(t);
ReleaseSemaphore(semEmpty_, 1, NULL);
}
T take()
{
WaitForSingleObject(semEmpty_, INFINITE);
assert(!queue_.empty());
T front(queue_.front());
queue_.pop_front();
ReleaseSemaphore(semFull_, 1, NULL);
return front;
}
size_t size() const { return queue_.size(); }
private:
void init()
{
semFull_ = CreateSemaphore(NULL, num_, num_, NULL);
semEmpty_ = CreateSemaphore(NULL, 0, num_, NULL);
assert(NULL != semFull_);
assert(NULL != semEmpty_);
}
private:
int num_;
HANDLE semFull_;
HANDLE semEmpty_;
std::deque<T> queue_;
};
#endif // SPEND_BLOCKQUEUE_H_
#pragma once
#include "mutex_lock.h"
#include <WinBase.h>
namespace util {
bool IsWindowsXP()
{
return true;
static int result = -1;
if (-1 == result) {
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
bool isXp = osvi.dwMajorVersion < 6;
result = isXp ? 1 : 0;
return result ? true : false;
}
return result ? true : false;
}
}
class Condition
{
public:
explicit Condition(CMutexLock &mutex)
: mutex_(mutex)
{
if (util::IsWindowsXP()) {
cond_ = new CondType();
((CondType*)cond_)->signal = CreateEvent(NULL, false, false, NULL);
((CondType*)cond_)->broadcast = CreateEvent(NULL, true, false, NULL);
} else {
cond_ = new CONDITION_VARIABLE();
InitializeConditionVariable((PCONDITION_VARIABLE)cond_);
}
}
Condition::~Condition()
{
if (util::IsWindowsXP()) {
CondType *p = (CondType*)cond_;
CloseHandle(p->signal);
CloseHandle(p->broadcast);
delete p;
} else {
CONDITION_VARIABLE *p = (CONDITION_VARIABLE*)cond_;
delete p;
}
}
void wait()
{
if (util::IsWindowsXP()) {
mutex_.unlock();
HANDLE handles[] = {((CondType*)cond_)->signal, ((CondType*)cond_)->broadcast};
WaitForMultipleObjects(2, handles, false, INFINITE);
mutex_.lock();
} else {
SleepConditionVariableCS((PCONDITION_VARIABLE)cond_, (CRITICAL_SECTION*)(mutex_.cs()), INFINITE);
}
}
void notify()
{
if (util::IsWindowsXP()) {
SetEvent(((CondType*)cond_)->signal);
} else {
WakeConditionVariable((PCONDITION_VARIABLE)cond_);
}
}
private:
Condition(const Condition&);
Condition& operator=(const Condition&);
private:
CMutexLock &mutex_;
void *cond_;
typedef struct { HANDLE signal, broadcast; } CondType;
};