我有以下代码:
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;
}
};
在Qt线程中:
的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;
}
在另一个主题中:
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_);
}
但是,在主线程中,我有一个功能,使用户可以单击按钮来获取当前图像:
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));
}
问题是:
当用户未单击按钮调用Producer :: SaveImage()时,图像解码和显示会顺利运行。但是当用户调用Producer :: SaveImage()时,整个程序都会卡住(卡顿现象?)。 GUI响应变得不那么顺利。用户调用SaveImage越多,GUI响应就越慢。
任何人都可以帮忙解释原因吗?有没有办法解决这个问题?
答案 0 :(得分:0)
为什么要使用并发队列?看起来有一个同步机制,你主要依赖它,而不是像class D extends A with C with B {
override def print(): Unit = super.print()
}
那样使用concurrent_queue
进行同步和通信。
问题是,当您设置capacity = 1时,concurrent_bounded_queue
的两个操作都将阻塞,直到队列中有足够的项目空间。例如。如果队列中已包含项目,则push
操作将被阻止。而且,由于您使用其他通知机制控制线程,因此可能会遇到死锁。
特别是,尝试交换下面的操作:
camera_queue_.pop(cur_image_);
emit imageReady();
image_queue_.push(cur_image_);
这应该准备接收图像的线程(如果我理解正确的话)并且它将阻塞其image_queue_.pop()
方法,那么这个线程将放置新图像并解锁收件人。可能存在与此类似的其他问题,因此,请重新考虑所有同步。