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. How to restart a thread?
Forum Updated to NodeBB v4.3 + New Features

How to restart a thread?

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 722 Views 2 Watching
  • 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.
  • W Offline
    W Offline
    Wiru
    wrote on 1 Sept 2020, 08:11 last edited by
    #1

    How to properly restart a QThread? I have been googling this four hours and can't find any concrete answer.

    What I have is the basic moveToThread implementation:

    VideoHandler::VideoHandler()
    {
        VideoBurner *videoBurner = new VideoBurner;
        videoBurner->moveToThread(&videoBurnerThread);
    
        connect(this, &VideoHandler::signalVideoData, videoBurner, &VideoBurner::setVideoData);
        connect(this, &VideoHandler::signalVideoBurn, videoBurner, &VideoBurner::initVideoBurn);
    
        // don't really want it since there is only 1 object
        //connect(&videoBurnerThread, &QThread::finished, videoBurner, &QObject::deleteLater);
    
        connect(videoBurner, &VideoBurner::burnProcess, this, [=](QString step, int percentage){
            emit burningProcess(step, percentage);
        });
    }
    

    This is the declaration of my Class:

    class VideoHandler : public QObject
    {
        Q_OBJECT
        QThread videoBurnerThread;
    ... 
    bunch of defintions
    ...
    }
    

    The VideoBurner class is also a subclass of QObject

    class VideoBurner : public QObject
    {
        Q_OBJECT
    ...
    bunch of definitions
    ...
    }
    

    For the first run this works perfect, signals and slots all work.
    The issue happens when I want to "cancel" the thread.
    For example it is working on some "heavy" calculation that I want to stop from the main thread so I call: videoBurnerThread.quit(); with a cancel function from VideoHandler.

    I don't wait() on it as it would block the main thread.

    quit() triggers &QThread::finished, but I commented out that connection as it destroys my only object instance.

    (also I can't find any example that creates an object and puts it on a thread outside a constructor, if that's even possible? when I tried the app would just close without errors)

    I found that the quit() only stops the event loop, not doing anything besides that, which leads to the issue of restarting the tread.

    After I want to do the "heavy" stuff again, and I call videoBurnerThread.start(); to start it again, I get results of last performed function from VideoBurner and some signals from it, before it actually starts doing what it should.

    Can I somehow stop whatever it was working on and just restart it? I tried sending an "abort" signal from VideoHandler so it doesn't emit signals, but that didn't work.

    Do I absolutely need the &QObject::deleteLater so it stops? If so, how to reinitialize VideoBurner correctly inside some function and reconnect it's signal/slot?

    Also there is no logic in VideoBurner destructor just a public: virtual ~VideoBurner(){};, could this be an issue?

    J 1 Reply Last reply 1 Sept 2020, 13:52
    0
    • W Wiru
      1 Sept 2020, 08:11

      How to properly restart a QThread? I have been googling this four hours and can't find any concrete answer.

      What I have is the basic moveToThread implementation:

      VideoHandler::VideoHandler()
      {
          VideoBurner *videoBurner = new VideoBurner;
          videoBurner->moveToThread(&videoBurnerThread);
      
          connect(this, &VideoHandler::signalVideoData, videoBurner, &VideoBurner::setVideoData);
          connect(this, &VideoHandler::signalVideoBurn, videoBurner, &VideoBurner::initVideoBurn);
      
          // don't really want it since there is only 1 object
          //connect(&videoBurnerThread, &QThread::finished, videoBurner, &QObject::deleteLater);
      
          connect(videoBurner, &VideoBurner::burnProcess, this, [=](QString step, int percentage){
              emit burningProcess(step, percentage);
          });
      }
      

      This is the declaration of my Class:

      class VideoHandler : public QObject
      {
          Q_OBJECT
          QThread videoBurnerThread;
      ... 
      bunch of defintions
      ...
      }
      

      The VideoBurner class is also a subclass of QObject

      class VideoBurner : public QObject
      {
          Q_OBJECT
      ...
      bunch of definitions
      ...
      }
      

      For the first run this works perfect, signals and slots all work.
      The issue happens when I want to "cancel" the thread.
      For example it is working on some "heavy" calculation that I want to stop from the main thread so I call: videoBurnerThread.quit(); with a cancel function from VideoHandler.

      I don't wait() on it as it would block the main thread.

      quit() triggers &QThread::finished, but I commented out that connection as it destroys my only object instance.

      (also I can't find any example that creates an object and puts it on a thread outside a constructor, if that's even possible? when I tried the app would just close without errors)

      I found that the quit() only stops the event loop, not doing anything besides that, which leads to the issue of restarting the tread.

      After I want to do the "heavy" stuff again, and I call videoBurnerThread.start(); to start it again, I get results of last performed function from VideoBurner and some signals from it, before it actually starts doing what it should.

      Can I somehow stop whatever it was working on and just restart it? I tried sending an "abort" signal from VideoHandler so it doesn't emit signals, but that didn't work.

      Do I absolutely need the &QObject::deleteLater so it stops? If so, how to reinitialize VideoBurner correctly inside some function and reconnect it's signal/slot?

      Also there is no logic in VideoBurner destructor just a public: virtual ~VideoBurner(){};, could this be an issue?

      J Offline
      J Offline
      JKSH
      Moderators
      wrote on 1 Sept 2020, 13:52 last edited by
      #2

      @Wiru said in How to restart a thread?:

      For example it is working on some "heavy" calculation that I want to stop from the main thread so I call: videoBurnerThread.quit(); with a cancel function from VideoHandler.

      If your VideoBurner object is in the middle of a calculation and you quit the event loop, your VideoBurner will enter "suspended animation". It will remain stuck in its half-calculated state... and then it will continue the calculation when the event loop is restarted.

      To avoid that, you must get your VideoBurner object to discard its incomplete calculations when you want to quit.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      W 1 Reply Last reply 1 Sept 2020, 14:29
      1
      • J JKSH
        1 Sept 2020, 13:52

        @Wiru said in How to restart a thread?:

        For example it is working on some "heavy" calculation that I want to stop from the main thread so I call: videoBurnerThread.quit(); with a cancel function from VideoHandler.

        If your VideoBurner object is in the middle of a calculation and you quit the event loop, your VideoBurner will enter "suspended animation". It will remain stuck in its half-calculated state... and then it will continue the calculation when the event loop is restarted.

        To avoid that, you must get your VideoBurner object to discard its incomplete calculations when you want to quit.

        W Offline
        W Offline
        Wiru
        wrote on 1 Sept 2020, 14:29 last edited by
        #3

        @JKSH said in How to restart a thread?:

        If your VideoBurner object is in the middle of a calculation and you quit the event loop, your VideoBurner will enter "suspended animation". It will remain stuck in its half-calculated state... and then it will continue the calculation when the event loop is restarted.
        To avoid that, you must get your VideoBurner object to discard its incomplete calculations when you want to quit.

        Thank you for the info, I'll search for how to achieve this.

        1 Reply Last reply
        0

        1/3

        1 Sept 2020, 08:11

        • Login

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