windows阻塞队列


// 互斥锁

#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;
};


评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值