Ich habe den folgenden Code:TBB concurrent_bounded_queue mehr Threads zugreifen
tbb::concurrent_bounded_queue<Image> camera_queue_;
camera_queue_.set_capacity(1);
struct Image
{
int hour_;
int minute_;
int second_;
int msec_;
QImage image_;
Image(){hour_ = -1; minute_ = -1; second_ = -1; msec_ = -1; image_ = QImage();}
Image& operator=(Image const& copy)
{
this->hour_ = copy.hour_;
this->minute_ = copy.minute_;
this->second_ = copy.second_;
this->msec_ = copy.msec_;
this->image_ = copy.image_;
return *this;
}
};
In einem Qt Thema:
ThreadA:
tbb::concurrent_bounded_queue<Image> image_queue_;
image_queue_.set_capacity(1);
Image cur_image_;
void Worker::process() {
while(1)
{
if(quit_)
break;
{
camera_queue_.pop(cur_image_);
image_queue_.push(cur_image_);
}
emit imageReady();
}
emit finished();
}
Image Worker::getCurrentImage()
{
Image tmp_image;
image_queue_.pop(tmp_image);
return tmp_image;
}
in einem anderen Thread:
ThreadB:
Producer::Producer(){
work_ = new Worker();
work_->moveToThread(workerThread_);
QObject::connect(workerThread_, &QThread::finished, work_, &QObject::deleteLater);
QObject::connect(this, &Producer::operate, work_, &Worker::process);
QObject::connect(work_, &Worker::imageReady, this, &Producer::displayImage);
QObject::connect(this, &Producer::stopDecode, work_, &Worker::stop);
workerThread_->start();
emit operate();
}
void Producer::process() {
while(1)
{
if(quit_)
break;
{
camera_queue_.push(GetImage());
}
}
}
void Producer::displayImage()
{
Image tmp = std::move(work_->getCurrentImage());
widget_->showImage(tmp.image_);
}
jedoch im Hauptthread, ich habe eine Funktion, die Benutzer ermöglicht, eine Schaltfläche klicken aktuelles Bild zu erhalten:
bool Producer::SaveImage()
{
Image img = std::move(work_->getCurrentImage());
std::string fileName = std::to_string(img.hour_) + "-" + std::to_string(img.minute_) + "-" + std::to_string(img.second_) + "-" + std::to_string(img.msec_/1000) + ".jpg";
std::string outFileName = folder + "/" + fileName;
return img.image_.save(QString::fromStdString(outFileName));
}
Das Problem ist:
Wenn Benutzer rufen nicht auf die Schaltfläche klicken, um Producer :: SaveImage(), die Bilddecodierung und -darstellung läuft reibungslos. Aber wenn der Benutzer Producer :: SaveImage() aufruft, bleibt das ganze Programm hängen (Caton-Phänomen?). Die GUI-Antwort wird nicht so glatt. Je mehr Benutzer SaveImage aufrufen, desto langsamer wird die GUI-Antwort.
Kann jemand helfen, warum zu erklären? Gibt es eine Möglichkeit, das zu lösen?
Die camera_queue_ (concurrent_bounded_queue mit der Kapazität 1) wird zum Abrufen von Bilddaten aus einem Live-Video verwendet. Und die image_queue_ (concurrent_bounded_queue mit der Kapazität 1) wird für den Anzeige- oder Speichervorgang verwendet. Wo ist der mögliche Stillstand? Ich habe zwei gleichzeitige Warteschlangen getrennt verwendet. Kannst du darauf hinweisen? Vielen Dank. – Johnnylin
Das Signal emit imageReady() dient nur zum Aufrufen der Producer-Instanz, um das Image von image_queue_ zu erhalten, um es im Hauptthread anzuzeigen. – Johnnylin
Stellen Sie sich nun vor, dass Producer immer noch ein Element in der Warteschlange hat. In der Reihenfolge der Operationen wird Push blockiert und Producer wird nicht aufgerufen. – Anton