Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt multi-threaded display synchronization problem

Qt multi-threaded display synchronization problem

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 3 Posters 335 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    hujh
    wrote on last edited by
    #1

    We developed an image processing and display program based on Qt. We use sub-threads for image processing and the main thread as UI display. In order to display synchronization, we use the Qt::BlockingQueuedConnection parameter when connecting the signal-slot. There are other threads that may overwrite the image data, so we use locks. code show as below:

    class ProcessThread : public QThread
    {
        Q_OBJECT
    public:
        ProcessThread(QObject *parent = nullptr);
    
        void run() override
        {
            int i=0;
            while (1)
            {
                if(isQuit)break;
    
                mutex.lock();
    
                QString filename=QString("/home/%1.bmp").arg((i++)%2000);
                data=imread(filename.toStdString());
    
                //dosomthing...
    
                emit processCompleted(&data);
    
                mutex.unlock();
            }
        }
    
        void setIsQuit(bool v){isQuit=v;}
    
    signals:
        void processCompleted(const Mat *data);
    
    private:
        bool isQuit=false;
        Mat data;
        QMutex mutex;
    };
    
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = nullptr): QWidget(parent)
        {
            thread=new ProcessThread();
    
            connect(thread,SIGNAL(processCompleted(const Mat *)),
                    this,SLOT(processCompleted(const Mat *)),Qt::BlockingQueuedConnection);
    
            thread->start();
        }
    
        ~Widget()
        {
            thread->setIsQuit(true);
    
            thread->quit();
            thread->wait();
            delete thread;
        }
    
        void paintEvent(QPaintEvent *event) override
        {
            Q_UNUSED(event)
            QPainter p(this);
            p.drawImage(QPoint(0,0),image);
        }
    
    private slots:
        void processCompleted(const Mat *data)
        {
            if(data!=nullptr)
            {
                if(data->channels()==1)
                {
                    image=QImage(data->data,
                                 data->cols,
                                 data->rows,
                                 data->step,
                                 QImage::Format_Grayscale8);
                }
                else
                {
                    image=QImage(data->data,
                                 data->cols,
                                 data->rows,
                                 data->step,
                                 QImage::Format_RGB888);
                }
            }
            else
            {
                image=QImage();
            }
    
            repaint();
        }
    
    private:
        QImage image;
        ProcessThread *thread;
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
        return a.exec();
    }
    

    1、When I exit the program, it will be stuck in thread->wait() in the ~Widget() function; it cannot continue to execute;
    2、If I comment out thread->wait(); it will not get stuck when exiting, but it will prompt: "QMutex: destroying locked mutex" and "QThread: Destroyed while thread is still running" errors;
    3、、If the Qt::BlockingQueuedConnection parameter is not used when connecting the signal-slot, the first problem above will not occur, but the display will not be synchronized.

    If BlockingQueuedConnection is not used, the processing thread will not be synchronized with the UI main thread, that is, the processing thread will not wait for the display refresh of the UI main thread, which will cause display confusion. So we need to display synchronization. And I put the image processing thread in the QtConcurrent framework, but it still deadlocks when wairForFinished().

    How to achieve multi-threaded display synchronization without causing blocking? Thanks!

    Christian EhrlicherC 1 Reply Last reply
    0
    • H hujh

      We developed an image processing and display program based on Qt. We use sub-threads for image processing and the main thread as UI display. In order to display synchronization, we use the Qt::BlockingQueuedConnection parameter when connecting the signal-slot. There are other threads that may overwrite the image data, so we use locks. code show as below:

      class ProcessThread : public QThread
      {
          Q_OBJECT
      public:
          ProcessThread(QObject *parent = nullptr);
      
          void run() override
          {
              int i=0;
              while (1)
              {
                  if(isQuit)break;
      
                  mutex.lock();
      
                  QString filename=QString("/home/%1.bmp").arg((i++)%2000);
                  data=imread(filename.toStdString());
      
                  //dosomthing...
      
                  emit processCompleted(&data);
      
                  mutex.unlock();
              }
          }
      
          void setIsQuit(bool v){isQuit=v;}
      
      signals:
          void processCompleted(const Mat *data);
      
      private:
          bool isQuit=false;
          Mat data;
          QMutex mutex;
      };
      
      
      class Widget : public QWidget
      {
          Q_OBJECT
      
      public:
          Widget(QWidget *parent = nullptr): QWidget(parent)
          {
              thread=new ProcessThread();
      
              connect(thread,SIGNAL(processCompleted(const Mat *)),
                      this,SLOT(processCompleted(const Mat *)),Qt::BlockingQueuedConnection);
      
              thread->start();
          }
      
          ~Widget()
          {
              thread->setIsQuit(true);
      
              thread->quit();
              thread->wait();
              delete thread;
          }
      
          void paintEvent(QPaintEvent *event) override
          {
              Q_UNUSED(event)
              QPainter p(this);
              p.drawImage(QPoint(0,0),image);
          }
      
      private slots:
          void processCompleted(const Mat *data)
          {
              if(data!=nullptr)
              {
                  if(data->channels()==1)
                  {
                      image=QImage(data->data,
                                   data->cols,
                                   data->rows,
                                   data->step,
                                   QImage::Format_Grayscale8);
                  }
                  else
                  {
                      image=QImage(data->data,
                                   data->cols,
                                   data->rows,
                                   data->step,
                                   QImage::Format_RGB888);
                  }
              }
              else
              {
                  image=QImage();
              }
      
              repaint();
          }
      
      private:
          QImage image;
          ProcessThread *thread;
      };
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
          Widget w;
          w.show();
          return a.exec();
      }
      

      1、When I exit the program, it will be stuck in thread->wait() in the ~Widget() function; it cannot continue to execute;
      2、If I comment out thread->wait(); it will not get stuck when exiting, but it will prompt: "QMutex: destroying locked mutex" and "QThread: Destroyed while thread is still running" errors;
      3、、If the Qt::BlockingQueuedConnection parameter is not used when connecting the signal-slot, the first problem above will not occur, but the display will not be synchronized.

      If BlockingQueuedConnection is not used, the processing thread will not be synchronized with the UI main thread, that is, the processing thread will not wait for the display refresh of the UI main thread, which will cause display confusion. So we need to display synchronization. And I put the image processing thread in the QtConcurrent framework, but it still deadlocks when wairForFinished().

      How to achieve multi-threaded display synchronization without causing blocking? Thanks!

      Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @hujh said in Qt multi-threaded display synchronization problem:

      3、、If the Qt::BlockingQueuedConnection parameter is not used when connecting the signal-slot, the first problem above will not occur, but the display will not be synchronized.

      Because you pass a pointer to data which you instantly overwrite with new data - what do you expect?

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        Beside the memory management issue pointed by @Christian-Ehrlicher, can you explain what synchronization you are talking about ? Your code has a single worker thread and your GUI shows only the result.

        You should rather take inspiration from the Mandelbrot example.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved