Это правильный способ реализации ограниченного буфера в C ++ [закрыто]
Я работаю над программой, которая имеет дело с несколькими потоками, осуществляющими доступ, ввод и вывод из ограниченного буферного контейнера. Я заметил некоторые серьезные проблемы с потоками и подозреваю, что мой буфер где-то частично или принципиально неверен.
Чтобы быть уверенным, что я знаю, что я делаю с этим, я был бы признателен за просмотр моего буферного кода. В этом классе используется семафор, который я реализовал в другом месте, и который, как я предполагаю, работает на данный момент (если нет, я это скоро выясню!) Я добавил комментарии, которые пытаются объяснить мои рассуждения.
Сначала файл .h:
#ifndef BOUNDED_BUFFER_H
#define BOUNDED_BUFFER_H
#include "Semaphore.H"
#include <string>
#include <vector>
using namespace std;
class Item{ //supposed to eventually be more extensible...seems silly with just a string for now
public:
Item(string _content){content = _content;}
string GetContent() {return content;}
private:
};
class BoundedBuffer{
public:
BoundedBuffer();
void Deposit(Item* _item);
Item* Retrieve();
int GetNumItems() {return count;}
vector<Item*> GetBuffer() {return buffer;}
void SetSize(int _size){
capacity = _size;
buffer.reserve(_size); //or do I need to call "resize"
}
private:
int capacity;
vector<Item*> buffer; //I originally wanted to use an array but had trouble with
//initilization/sizing, etc.
int nextin;
int nextout;
int count;
Semaphore notfull; //wait on this one before depositing an item
Semaphore notempty; //wait on this one before retrieving an item
};
#endif
Далее .cpp:
#include "BoundedBuffer.H"
#include <iostream>
using namespace std;
BoundedBuffer::BoundedBuffer(){
notfull.SetValue(0);
notempty.SetValue(0);
nextin = 0;
nextout = 0;
count = 0;
}
void BoundedBuffer::Deposit(Item* _item){
if(count == capacity){
notfull.P(); //Cannot deposit into full buffer; wait
}
buffer[nextin] = _item;
nextin = (nextin + 1) % capacity; //wrap-around
count += 1;
notempty.V(); //Signal that retrieval is safe
}
Item* BoundedBuffer::Retrieve(){
if(count == 0){
notempty.P(); //cannot take from empty buffer; wait
}
Item* x = buffer[nextout];
nextout = (nextout + 1) % capacity;
buffer.pop_back(); //or a different erase methodology?
count -= 1;
notfull.V(); //Signal that deposit is safe
return x;
}
Я думаю, что проблемы могут возникнуть из-за моего выбора вектора в качестве базового контейнера (или, скорее, из-за его неправильного использования), или, возможно, из-за необходимости в дополнительных блокирующих механизмах безопасности (блокировки мьютекса и т. Д.) Из-за внешнего вида вещи, кто-нибудь может предложить какой-то отзыв?