// 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;}
新闻热点
疑难解答