// block1
#pragma once
#include <list>
#include <assert.h>
#include <Windows.h>
class MutexLock
{
public:
MutexLock()
{
InitializeCriticalSection(&m_criticalSection);
}
~MutexLock()
{
DeleteCriticalSection(&m_criticalSection);
}
void lock()
{
EnterCriticalSection(&m_criticalSection);
}
void unlock()
{
LeaveCriticalSection(&m_criticalSection);
}
CRITICAL_SECTION& cs()
{
return m_criticalSection;
}
private:
MutexLock(const MutexLock&);
MutexLock& operator=(const MutexLock&);
CRITICAL_SECTION m_criticalSection;
};
template<typename T>
class BlockQueue
{
public:
BlockQueue(int num = 256)
: m_num(num)
{
init();
}
~BlockQueue()
{
CloseHandle(m_semFull);
CloseHandle(m_semEmpty);
}
void put(const T &t)
{
WaitForSingleObject(m_semFull, INFINITE);
m_mutexLock.lock();
m_queue.push_back(t);
m_mutexLock.unlock();
ReleaseSemaphore(m_semEmpty, 1, NULL);
}
void take(T &value)
{
WaitForSingleObject(m_semEmpty, INFINITE);
m_mutexLock.lock();
assert(!m_queue.empty());
value = m_queue.front();
m_queue.pop_front();
m_mutexLock.unlock();
ReleaseSemaphore(m_semFull, 1, NULL);
}
size_t size() const
{
return m_queue.size();
}
private:
void init()
{
m_semFull = CreateSemaphore(NULL, m_num, m_num, NULL);
m_semEmpty = CreateSemaphore(NULL, 0, m_num, NULL);
assert(NULL != m_semFull);
assert(NULL != m_semEmpty);
}
private:
int m_num;
MutexLock m_mutexLock;
HANDLE m_semFull;
HANDLE m_semEmpty;
std::list<T> m_queue;
};
//block2
#pragma once
#include <condition_variable>
#include <list>
#include <assert.h>
template<typename T>
class BlockQueue2
{
public:
BlockQueue2() : m_mutex(), m_condvar(), m_queue()
{
}
void put(const T& task)
{
{
std::lock_guard<std::mutex> lock(m_mutex);
m_queue.push_back(task);
}
m_condvar.notify_all();
}
void take(T &value)
{
std::unique_lock<std::mutex> lock(m_mutex);
m_condvar.wait(lock, [this]{return !m_queue.empty(); });
assert(!m_queue.empty());
value = m_queue.front();
m_queue.pop_front();
}
size_t size() const
{
std::lock_guard<std::mutex> lock(m_mutex);
return m_queue.size();
}
private:
BlockQueue2(const BlockQueue2& rhs);
BlockQueue2& operator = (const BlockQueue2& rhs);
private:
mutable std::mutex m_mutex;
std::condition_variable m_condvar;
std::list<T> m_queue;
};
//main
//test.cpp
#include "SyncQueue.h"
#include "SyncQueue2.h"
#include <thread>
#include <iostream>
#include <chrono>
#include <time.h>
#include <stdlib.h>
BlockQueue<int> syncQueue;
//BlockQueue2<int> syncQueue;
void Produce(int producerID)
{
/*while (true)
{
//std::this_thread::sleep_for(std::chrono::seconds(1));
srand((unsigned)time(NULL));
int x = rand() % 1000;
syncQueue.Put(x);
std::cout << "consumer[" << consumerID << "] take:" << x << std::endl;
}*/
for (int i = 0; i < 100; ++i)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
syncQueue.put(i);
//std::cout << "put:" << i << std::endl;
std::cout << "producer[" << producerID << "] put:" << i << std::endl;
}
}
void Consume(int consumerID)
{
int x = 0;
while (true)
{
//std::this_thread::sleep_for(std::chrono::seconds(1));
syncQueue.take(x);
std::cout << "consumer[" << consumerID << "] take:" << x << std::endl;
}
}
int main(void)
{
std::thread producer1(Produce, 1);
std::thread producer2(Produce, 2);
std::thread consumer1(Consume, 1);
std::thread consumer2(Consume, 2);
std::thread consumer3(Consume, 3);
producer1.join();
producer2.join();
consumer1.join();
consumer2.join();
consumer3.join();
return 0;
}