多线程建议

时间:2015-12-08 14:27:15

标签: c++ multithreading qt opencv

我正在开发一个应用程序,主要目标是从图像采集器中获取图像,进行一些处理,然后在GUI上显示图像。 帧抓取器连接到PCIe。我正在使用帧抓取器SDK。 图像流速度非常慢,为10到100张图像/秒 我在这里对我的代码以及如何优化它有一些建议。 首先,我从一个继承自Qthread的类中运行run()函数 我抓取一个图像并将其放在缓冲区queuecv :: Mat&gt ;.

void ImageIn::run(){
        _cam->allocMemory();
        _cam->startAquisition();
        _runningThread = true;

        while(_runningThread)
        {
             Mat image(_cam.getSizeX(), _cam.getSizeY(), CV_16U, _cam->getImageDMA0());

             _ctrl->getMutexIn()->lock(); // Lock BufferIn
             _ctrl->getBufferIn()->push(image); // store Image in BufferIn
             _ctrl->getMutexIn()->unlock(); // Unlock bufferIn
        }

}

图像存储在缓冲区中,然后处理线程做一些工作......

void ImageProcessing::run(){
while(_runningThread){
if (_ctrl->getMutexIn()->tryLock()){
    while(!_ctrl->getBufferIn()->empty()){
        _ctrl->getBufferIn()->front().convertTo(tempConvert, CV_32F);
        _bufferLocalIn.push(tempConvert);
        _ctrl->getBufferIn()->pop();
    }
    _ctrl->getMutexIn()->unlock();
}

// Do some processing and put image and a buffer for GUI
}
}

所以,我有一些问题: - 由于阻塞功能,线程1获取图像,因此CPU消耗很低,但线程2连续运行并消耗大量CPU重新评估我可以做些什么来修复它? - 这是编码的正确方法吗?

所以我试过了:

QThread* thread = new QThread;
ImageWriter* worker = new ImageWriter();
worker->moveToThread(thread);

QTimer* timer = new QTimer();
int msec = 100;
timer->setInterval(msec);

QObject::connect(thread, SIGNAL(started()), worker, SLOT(process()));
QObject::connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
QObject::connect(timer, SIGNAL(timeout()), thread, SLOT(start()));
timer->start();

没关系?

1 个答案:

答案 0 :(得分:2)

由于Qt是一个事件驱动的框架,每个线程都有一个事件队列,它接收事件并将它们发送到各种对象以接收它们。

如果一个线程中的任何代码段基本上都有一个while(1)循环,那么就不会发生事件传播,而这正是你在两个线程中所做的事情

while(_runningThread)

在无限循环中使事件处理匮乏是CPU消耗过多的原因。

可以使用Qt来处理在无限循环内调用QApplication::processEvents的事件,但这并不理想。

更好的方法是使用QTimer对处理进行时间分片,并允许事件传播自然发生。这将需要在保存处理状态然后返回到事件循环之前决定处理可能发生多长时间。计时器的勾号将调用您的处理函数,然后可以恢复状态并恢复。

如果您创建一个从QObject派生的处理类,您将更容易移动到QThread,而不是直接从QThread本身继承。在How to Really Truly Use QThread上有一篇很棒的文章,可以作为如何执行此操作的模板。

最后,请考虑您可以在QThread上运行多个QObject以及多个QThread。作为一般规则,如果线程数超过可用的处理器核心数,您将无法受益。

如果您知道目标机器是四核心,您可以创建3个额外的QThreads(总共4个,包括main),创建多个处理对象并将它们移动到不同的线程以提供最佳处理。