Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QThread - QThread::wait() does not terminate



  • I have a fairly simple QThread class that causes me quite some headaches. I assume it is something super obvious that I'm just missing.
    I'm using Qt 5.8 on Ubuntu with normal gcc toolchain.

    I have a simple OpenCV video feed capturing QThread:

    class VideoCaptureThread : public QThread
    {
        bool terminating;
        int id;
        VideoBuffer *buffer;
    
    public:
        VideoCaptureThread(int camID = 0, VideoBuffer *b = 0);
        virtual ~VideoCaptureThread();
    
        // QThread interface
    protected:
        void run() override;
    
    public slots:
        void stopCapuring();
        void setID(int);
        void setBuffer(VideoBuffer *);
    };
    

    with:

    VideoCaptureThread::VideoCaptureThread(int camID, VideoBuffer *b) :
        terminating(false),
        id(camID),
        buffer(b)
    {}
    
    VideoCaptureThread::~VideoCaptureThread(){
        cv::destroyWindow("CaptureThread Test");
        terminating = true;
    
        this->quit(); //I tried exit(0) or terminate() as well
        this->wait(); //Wait always blocks
    }
    
    void VideoCaptureThread::run(){
    
        //This all works fine
        cv::VideoCapture video(id);
        cv::Mat frame;
    
        while(!terminating && video.isOpened() && buffer != 0){
    
            video >> frame;
    
            cv::imshow("CaptureThread Test",frame);
    
            buffer->addFrame(frame);
            qDebug() << buffer->size();
    
            QCoreApplication::processEvents();
        }
    }
    
    void VideoCaptureThread::stopCapuring(){ terminating = true; }
    void VideoCaptureThread::setID(int i){ id = i; }
    void VideoCaptureThread::setBuffer(VideoBuffer *b){ buffer = b; }
    

    I call this by:

        VideoCaptureThread *capThread = new VideoCaptureThread( 0, &vBuffer);
        connect(this,SIGNAL(stopCapturing()), capThread, SLOT(deleteLater()));
    
        //alternatively I tried -> (but this caused SigSeg .. in my main() -> a.exec() <--- QApplication
        //connect(this,SIGNAL(stopCapturing()), capThread, SLOT(stopCaputing()));
        //connect(capThread,SIGNAL(finished()),capThread,SLOT(deleteLater()));
        
        capThread->start(QThread::HighestPriority);
    

    When I use all this, my application gets stuck at ~VideoCaptureThread (this.wait()).
    This is such a simple thread. But I still can't see the problem.

    I would appreciate your help.


  • Lifetime Qt Champion

    Hi,

    Quit will only work if run start's the thread event loop which is not your case.

    You are using a loop so you have to exit that loop for your thread to end which you do in the second line of your destructor.



  • This post is deleted!


  • Please see this thread from that point onward. You fell in the same misconceptions about QThread as that user. In your case you even have things like void VideoCaptureThread::setBuffer(VideoBuffer *b){ buffer = b; } as public which is a ticking time bomb.

    P.S.
    cv::imshow creates a window if I'm not mistaken and it should not be done in a secondary thread (on Windows your app would crash straight away)


Log in to reply