Хочу создать очередб с ожиданиями и с отказами, но что-то слетает 
есть циклический буфер
| Код | template <typename T> class CyclicBuffer { private : std::deque<T> container_; size_t maxSize_;
protected : virtual void OnOverflow (unsigned value) const { DebugMessage ("Debug", "Переполнение буфера"); }
public : typedef typename std::deque<T>::value_type value_type; typedef typename std::deque<T>::size_type size_type;
explicit CyclicBuffer (unsigned size) : maxSize_ (size) { assert (size); if (!maxSize_) { throw std::range_error ("Циклический буфер не может быть равен 0"); } } virtual ~CyclicBuffer () {;} void push (const value_type& value) { if (container_.size() == maxSize_) { OnOverflow (value->size()); container_.pop_front(); } container_.push_back (value); } void pop (void) { container_.pop_front (); } const value_type& get (void) const { return container_.front(); } void clear (void) { container_.clear(); } size_type size (void) const { return container_.size(); } size_type max_size (void) const { return maxSize_; } bool empty (void) const { return container_.empty(); } |
на его основе хочу создать очередь (поставщики-клиенты)
| Код | template <typename T> class Queue { private : CyclicBuffer<T> queue_; CRITICAL_SECTION section_ HANDLE semaphore_;
bool Lock (void) const {
DWORD result = WaitForSingleObject (semaphore_, 100); return (result == WAIT_OBJECT_0); } bool Unlock (void) const { return ReleaseSemaphore (semaphore_, 1, NULL)){ }
public : typedef typename CyclicBuffer<T>::value_type value_type;
explicit Queue (unsigned size) : queue_ (size){
InitializeCriticalSection (§ion_); semaphore_ = CreateSemaphore (NULL, 0, size, NULL); } virtual ~Queue () { CloseHandle (semaphore_); DeleteCriticalSection (§ion_); }
void push (const value_type& value) {
// если очередь заполнена, то ждем 100 мс. // если не дождались, то входим в критическую секцию и потеря данных if (!Unlock()) Lock (); EnterCriticalSection (§ion_); queue_.push (value); Unlock(); LeaveCriticalSection (§ion_); } bool pop (value_type& value) { // если очередь пуста, то ждем 100 мс // если не дождались, то выходим (flase) if (!Lock()) return false; EnterCriticalSection (§ion_); value = queue_.get(); queue_.pop(); LeaveCriticalSection (§ion_); return true; } void reset (void) { // входим в критическую секцию // числим очередь и сбрасываем семафор EnterCriticalSection (§ion_); for (int i = 0; i < queue_.size(); i++){ Lock(); } queue_.clear(); LeaveCriticalSection (§ion_); } unsigned max_size (void) const { return queue_.max_size(); } }; |
так вот получается, что, например, если я вхожу в критическую секцию reset() и сбрасываю семафор, то поток, который проверяет pop() пройдет условие и будет ждать входа в критическую секцию
как только я выйду из reset, поток в pop войдет, но очередь пуста !!!
Также и в push
Тоесть мне нужно как-то умудрится подождать очередь в pop и push, войти в критическую секцию и сделать свое дело |