Unsolved 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.
-
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 likevoid VideoCaptureThread::setBuffer(VideoBuffer *b){ buffer = b; }
aspublic
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)