Ist dies eine korrekte Methode, um einen begrenzten Puffer in C ++ zu implementieren? [Closed]
Ich arbeite an einem Programm, das sich mit mehreren Threads befasst, die auf einen begrenzten Puffercontainer zugreifen, ihn ablegen und ihn daraus entfernen. Ich habe einige schwerwiegende Probleme mit den Threads festgestellt und vermute, dass mein Puffer teilweise oder grundlegend falsch ist.
Um sicherzugehen, dass ich weiß, was ich damit mache, würde ich es begrüßen, wenn mein Puffercode überprüft würde. Die Klasse verwendet ein Semaphor, das ich an anderer Stelle implementiert habe. Ich gehe davon aus, dass es jetzt funktioniert (wenn nicht, werde ich das früh genug herausfinden!). Ich habe Kommentare hinzugefügt, die versuchen, meine Argumentation zu erklären.
Zunächst die .h-Datei:
#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
Als nächstes die .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;
}
Ich denke, dass Probleme durch die Wahl eines Vektors als zugrunde liegenden Container (oder vielmehr durch eine falsche Verwendung davon) oder durch die Notwendigkeit weiterer Sicherheitsblockierungsmechanismen (Mutex-Sperren usw.) entstehen können Dinge, kann jemand Feedback geben?