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. Randomly getting "QThread: Destroyed while thread is still running"
Forum Updated to NodeBB v4.3 + New Features

Randomly getting "QThread: Destroyed while thread is still running"

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 7 Posters 10.0k Views 3 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.
  • S stretchthebits

    What are the threads doing? What does the code for the thread look like?

    AlveinA Offline
    AlveinA Offline
    Alvein
    wrote on last edited by Alvein
    #6

    @stretchthebits said

    What are the threads doing? What does the code for the thread look like?

    Originally, calling some REST service, but I've just replaced that with some random QThread::msleep() and the problem persisted.

    @ChrisW67 said

    All the examples I see use the finished() signal and deleteLater(), but then they are not polling in an event driven system.

    Thanks for the suggestions. I've modified the code (and now I have another problem). See below.

    @Kent-Dorfman said

    Using IsRunning() is dangerous as there is no guarantee that the thread remains running even a few milliseconds after the call. Use catch the finished() signal and use deletelater as others have mentioned. Also even start() doesn't guarantee immediate execution. It just adds the thread to the scheduler.

    Thanks for the suggestions. TBH, I suspected that but just gave it a go.

    One thing that bothers me a lot is the fact that isRunning() and isFinished() are not something to trust in. Then what do they exist for in first place?

    @jsulm said

    You should stop your threads properly. Use https://doc.qt.io/qt-5/qthread.html#requestInterruption and https://doc.qt.io/qt-5/qthread.html#isInterruptionRequested to ask each thread to stop and then call https://doc.qt.io/qt-5/qthread.html#wait on each thread.

    I'll leave this for later, since the threads I'm using don't need to be forcefully stopped. They just finish themselves.

    ....

    I've modified the code to something simple. Now, I am not continuously creating and destroying threads. I create everything in a single shot, and later, start the available ones as soon as others finish.

    This should be simpler, but I am having a new (random) error:

    "...(first chance) in MSVCP140D!std::_Throw_future_error"
    "...abort() has been called"

    This is the new code:

    #define TOTAL_WORKERS 10
    #define TOTAL_ACTIVE   4
    
    void MainWindow::some_slot() {
        int iK;
        // ...
        for(iK=0;iK<TOTAL_WORKERS;iK++) {
            thlWorkers[iK]=QThread::create([]{/*...*/});
            connect(thlWorkers[iK],SIGNAL(finished()),this,SLOT(on_finished()));
        }
        for(iK=0;iK<TOTAL_ACTIVE;iK++)
            thlWorkers.at(iK)->start();
        // ...
    }
    
    void MainWindow::on_finished() {
        int iK=getOneFreeWorkerIndex();
        thlWorkers.at(iK)->wait();
        thlWorkers.at(iK)->start();
    }
    

    For simplicity, let's assume that I don't need to stop the process once it starts.

    Also, please consider getOneFreeWorkerIndex() as just a random pick. In practice, it should choose one worker based on its stats.

    And the following wait() should avoid starting an already running thread, right?

    OK, what's the problem here?

    Thanks to everyone for investing time in this.

    Kent-DorfmanK jsulmJ 2 Replies Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #7

      Hi,

      Might be a silly question but aren't you re-implementing QThreadPool ?

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

      C 1 Reply Last reply
      3
      • AlveinA Alvein

        @stretchthebits said

        What are the threads doing? What does the code for the thread look like?

        Originally, calling some REST service, but I've just replaced that with some random QThread::msleep() and the problem persisted.

        @ChrisW67 said

        All the examples I see use the finished() signal and deleteLater(), but then they are not polling in an event driven system.

        Thanks for the suggestions. I've modified the code (and now I have another problem). See below.

        @Kent-Dorfman said

        Using IsRunning() is dangerous as there is no guarantee that the thread remains running even a few milliseconds after the call. Use catch the finished() signal and use deletelater as others have mentioned. Also even start() doesn't guarantee immediate execution. It just adds the thread to the scheduler.

        Thanks for the suggestions. TBH, I suspected that but just gave it a go.

        One thing that bothers me a lot is the fact that isRunning() and isFinished() are not something to trust in. Then what do they exist for in first place?

        @jsulm said

        You should stop your threads properly. Use https://doc.qt.io/qt-5/qthread.html#requestInterruption and https://doc.qt.io/qt-5/qthread.html#isInterruptionRequested to ask each thread to stop and then call https://doc.qt.io/qt-5/qthread.html#wait on each thread.

        I'll leave this for later, since the threads I'm using don't need to be forcefully stopped. They just finish themselves.

        ....

        I've modified the code to something simple. Now, I am not continuously creating and destroying threads. I create everything in a single shot, and later, start the available ones as soon as others finish.

        This should be simpler, but I am having a new (random) error:

        "...(first chance) in MSVCP140D!std::_Throw_future_error"
        "...abort() has been called"

        This is the new code:

        #define TOTAL_WORKERS 10
        #define TOTAL_ACTIVE   4
        
        void MainWindow::some_slot() {
            int iK;
            // ...
            for(iK=0;iK<TOTAL_WORKERS;iK++) {
                thlWorkers[iK]=QThread::create([]{/*...*/});
                connect(thlWorkers[iK],SIGNAL(finished()),this,SLOT(on_finished()));
            }
            for(iK=0;iK<TOTAL_ACTIVE;iK++)
                thlWorkers.at(iK)->start();
            // ...
        }
        
        void MainWindow::on_finished() {
            int iK=getOneFreeWorkerIndex();
            thlWorkers.at(iK)->wait();
            thlWorkers.at(iK)->start();
        }
        

        For simplicity, let's assume that I don't need to stop the process once it starts.

        Also, please consider getOneFreeWorkerIndex() as just a random pick. In practice, it should choose one worker based on its stats.

        And the following wait() should avoid starting an already running thread, right?

        OK, what's the problem here?

        Thanks to everyone for investing time in this.

        Kent-DorfmanK Offline
        Kent-DorfmanK Offline
        Kent-Dorfman
        wrote on last edited by
        #8

        @Alvein said in Randomly getting "QThread: Destroyed while thread is still running":

        One thing that bothers me a lot is the fact that isRunning() and isFinished() are not something to trust in. Then what do they exist for in first place?

        those methods are only safe to syncronize operations "within the thread"...your attempted use is to use them to "control/manage" a threadpool. There is an important distinction because to effectively control or manage an item you need to have authoritative state information, but to syncronize an operation that on a thread the burden of safety is arguably much lower, especially if that synconization operation can be "error checked" as pass/fail.

        1 Reply Last reply
        0
        • SGaistS SGaist

          Hi,

          Might be a silly question but aren't you re-implementing QThreadPool ?

          C Offline
          C Offline
          ChrisW67
          wrote on last edited by
          #9

          @SGaist said in Randomly getting "QThread: Destroyed while thread is still running":

          Might be a silly question but aren't you re-implementing QThreadPool ?

          Maybe there's some unspoken requirement, but it seems likely to me that user controlled threads are not required to implement this at all. The threads are just 'calling some REST service' so QNetworkAccessManager can probably deal with it.

          1 Reply Last reply
          0
          • AlveinA Offline
            AlveinA Offline
            Alvein
            wrote on last edited by
            #10

            As I mentioned, this program is failing even if I use a simple QThread::msleep() per thread.

            I just want to have a given number of threads (TOTAL_WORKERS) but only a smaller amount (TOTAL_ACTIVE) running at time.

            Once one thread finishes, another one is started. That's all.

            That looks very simple, right?

            What's wrong with my implementation?

            jeremy_kJ 1 Reply Last reply
            0
            • AlveinA Alvein

              As I mentioned, this program is failing even if I use a simple QThread::msleep() per thread.

              I just want to have a given number of threads (TOTAL_WORKERS) but only a smaller amount (TOTAL_ACTIVE) running at time.

              Once one thread finishes, another one is started. That's all.

              That looks very simple, right?

              What's wrong with my implementation?

              jeremy_kJ Offline
              jeremy_kJ Offline
              jeremy_k
              wrote on last edited by
              #11

              @Alvein said in Randomly getting "QThread: Destroyed while thread is still running":

              I just want to have a given number of threads (TOTAL_WORKERS) but only a smaller amount (TOTAL_ACTIVE) running at time.

              What is having threads that are created but not immediately started intended to accomplish?

              Asking a question about code? http://eel.is/iso-c++/testcase/

              AlveinA 1 Reply Last reply
              1
              • jeremy_kJ jeremy_k

                @Alvein said in Randomly getting "QThread: Destroyed while thread is still running":

                I just want to have a given number of threads (TOTAL_WORKERS) but only a smaller amount (TOTAL_ACTIVE) running at time.

                What is having threads that are created but not immediately started intended to accomplish?

                AlveinA Offline
                AlveinA Offline
                Alvein
                wrote on last edited by
                #12

                @jeremy_k See them more as pending tasks. It's easier for me to set them all in advance, and the lambdas actually reference methods of other objects.

                I modified the original approach to follow some of the suggestions, but that's not important now.

                ANYWAY

                Is there a problem in starting again a thread which has already finished? I suspect this is the source of the problem.

                jeremy_kJ 1 Reply Last reply
                0
                • AlveinA Alvein

                  @jeremy_k See them more as pending tasks. It's easier for me to set them all in advance, and the lambdas actually reference methods of other objects.

                  I modified the original approach to follow some of the suggestions, but that's not important now.

                  ANYWAY

                  Is there a problem in starting again a thread which has already finished? I suspect this is the source of the problem.

                  jeremy_kJ Offline
                  jeremy_kJ Offline
                  jeremy_k
                  wrote on last edited by jeremy_k
                  #13

                  @Alvein said in Randomly getting "QThread: Destroyed while thread is still running":

                  @jeremy_k See them more as pending tasks. It's easier for me to set them all in advance, and the lambdas actually reference methods of other objects.

                  That sounds inefficient. Restructure the tasks as jobs in a queue, with a set of threads that take from the queue. Or better yet, use QThreadPool or Qt Concurrent to process the tasks, and get out of low level thread management altogether.

                  I modified the original approach to follow some of the suggestions, but that's not important now.

                  ANYWAY

                  Is there a problem in starting again a thread which has already finished? I suspect this is the source of the problem.

                  From QThread::create():

                  Warning: do not call start() on the returned QThread instance more than once; doing so will result in undefined behavior.

                  Asking a question about code? http://eel.is/iso-c++/testcase/

                  AlveinA 1 Reply Last reply
                  6
                  • jeremy_kJ jeremy_k

                    @Alvein said in Randomly getting "QThread: Destroyed while thread is still running":

                    @jeremy_k See them more as pending tasks. It's easier for me to set them all in advance, and the lambdas actually reference methods of other objects.

                    That sounds inefficient. Restructure the tasks as jobs in a queue, with a set of threads that take from the queue. Or better yet, use QThreadPool or Qt Concurrent to process the tasks, and get out of low level thread management altogether.

                    I modified the original approach to follow some of the suggestions, but that's not important now.

                    ANYWAY

                    Is there a problem in starting again a thread which has already finished? I suspect this is the source of the problem.

                    From QThread::create():

                    Warning: do not call start() on the returned QThread instance more than once; doing so will result in undefined behavior.

                    AlveinA Offline
                    AlveinA Offline
                    Alvein
                    wrote on last edited by
                    #14

                    @jeremy_k So the thing has been flawed since the very beginning.
                    Thanks for your help.

                    1 Reply Last reply
                    0
                    • AlveinA Alvein

                      @stretchthebits said

                      What are the threads doing? What does the code for the thread look like?

                      Originally, calling some REST service, but I've just replaced that with some random QThread::msleep() and the problem persisted.

                      @ChrisW67 said

                      All the examples I see use the finished() signal and deleteLater(), but then they are not polling in an event driven system.

                      Thanks for the suggestions. I've modified the code (and now I have another problem). See below.

                      @Kent-Dorfman said

                      Using IsRunning() is dangerous as there is no guarantee that the thread remains running even a few milliseconds after the call. Use catch the finished() signal and use deletelater as others have mentioned. Also even start() doesn't guarantee immediate execution. It just adds the thread to the scheduler.

                      Thanks for the suggestions. TBH, I suspected that but just gave it a go.

                      One thing that bothers me a lot is the fact that isRunning() and isFinished() are not something to trust in. Then what do they exist for in first place?

                      @jsulm said

                      You should stop your threads properly. Use https://doc.qt.io/qt-5/qthread.html#requestInterruption and https://doc.qt.io/qt-5/qthread.html#isInterruptionRequested to ask each thread to stop and then call https://doc.qt.io/qt-5/qthread.html#wait on each thread.

                      I'll leave this for later, since the threads I'm using don't need to be forcefully stopped. They just finish themselves.

                      ....

                      I've modified the code to something simple. Now, I am not continuously creating and destroying threads. I create everything in a single shot, and later, start the available ones as soon as others finish.

                      This should be simpler, but I am having a new (random) error:

                      "...(first chance) in MSVCP140D!std::_Throw_future_error"
                      "...abort() has been called"

                      This is the new code:

                      #define TOTAL_WORKERS 10
                      #define TOTAL_ACTIVE   4
                      
                      void MainWindow::some_slot() {
                          int iK;
                          // ...
                          for(iK=0;iK<TOTAL_WORKERS;iK++) {
                              thlWorkers[iK]=QThread::create([]{/*...*/});
                              connect(thlWorkers[iK],SIGNAL(finished()),this,SLOT(on_finished()));
                          }
                          for(iK=0;iK<TOTAL_ACTIVE;iK++)
                              thlWorkers.at(iK)->start();
                          // ...
                      }
                      
                      void MainWindow::on_finished() {
                          int iK=getOneFreeWorkerIndex();
                          thlWorkers.at(iK)->wait();
                          thlWorkers.at(iK)->start();
                      }
                      

                      For simplicity, let's assume that I don't need to stop the process once it starts.

                      Also, please consider getOneFreeWorkerIndex() as just a random pick. In practice, it should choose one worker based on its stats.

                      And the following wait() should avoid starting an already running thread, right?

                      OK, what's the problem here?

                      Thanks to everyone for investing time in this.

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #15

                      @Alvein said in Randomly getting "QThread: Destroyed while thread is still running":

                      I'll leave this for later, since the threads I'm using don't need to be forcefully stopped

                      Just a note: this is not forcefully stopping. You only ask the threads to stop, they don't have to do that immediately, they can even ignore this.

                      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