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. Cleaning up after a thread correcly
Forum Updated to NodeBB v4.3 + New Features

Cleaning up after a thread correcly

Scheduled Pinned Locked Moved General and Desktop
42 Posts 7 Posters 31.6k Views 1 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.
  • T Offline
    T Offline
    TheDestroyer
    wrote on last edited by
    #3

    Thank you for your reply.

    You're right about the switch thingy. I'll use it! and about exit and quit, what should I use instead????

    but concerning the new and delete commands... whenever I try to delete the thread, the program freezes! have you succeeded with that yourself? because I tried that like 10000 times with different methods with no success, and that's why I'm asking about a plan to clean up the thread professionally.

    So how can I use delete without quit()? please try it and you'll see how the program freezes!!!!

    If you know the way to go around this and use the thread cleanly, please tell me!

    1 Reply Last reply
    0
    • F Offline
      F Offline
      Franzk
      wrote on last edited by
      #4

      [quote author="romankr" date="1307306289"]@if(outputTypeString == "int16")
      {
      ...
      }
      else if(outputTypeString == "int32")
      {
      ...
      }
      else if(outputTypeString == "int64")
      {
      ...
      }@
      use switch ()[/quote]
      The switch statement only works on integer constants, not on (c-)strings.

      [quote]If you know the way to go around this and use the thread cleanly, please tell me![/quote]
      Make sure you react properly to exiting. Use exit() only if you properly handle that. Don't use terminate() unless you have a good reason to terminate it.

      I would always go with a
      @connect(myThread, SIGNAL(finished()), myThread, SLOT(deleteLater()));
      myThread->stopWorking();@

      This will delete your thread after it has finished its work. Only thing to do now is to make sure your main thread stays alive long enough to delete the thread object.

      "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

      http://www.catb.org/~esr/faqs/smart-questions.html

      1 Reply Last reply
      0
      • T Offline
        T Offline
        TheDestroyer
        wrote on last edited by
        #5

        Thank you for the answers guys. Sorry for the late reply, but my laptop got a problem and I had to format it!

        What do you mean with properly handle exiting? In the program, when the user clicks start, the thread is created, and the error could be issued in the thread immediately if the files don't exist, or if the user clicks the Stop button! So how could I handle exit() correctly here? is it just by issuing exit() on error? cuz this is what I'm doing. If the user clicks start again, a new thread is created and the old one is "lost" in memory... The problem is, as far as I see it, is that deleting threads take relatively long time. Isn't that true?

        so I can't tell the user "please wait till the thread is deleted".

        I'm thinking that since deleting threads takes long time, would it be a feasible solution to use a thread pool, in a way that whenever a thread fails, it's ignored by the program and handled by the pool for deletion, so that I could take another new thread from the pool when the user clicks Start again?

        1 Reply Last reply
        0
        • F Offline
          F Offline
          Franzk
          wrote on last edited by
          #6

          You could try and see if QtConcurrent helps you out.

          "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

          http://www.catb.org/~esr/faqs/smart-questions.html

          1 Reply Last reply
          0
          • G Offline
            G Offline
            giesbert
            wrote on last edited by
            #7

            [quote author="TheDestroyer" date="1307430591"]
            If the user clicks start again, a new thread is created and the old one is "lost" in memory... The problem is, as far as I see it, is that deleting threads take relatively long time. Isn't that true?
            [/quote]

            please define relatively long? The user recognizes it? Then it's a bug in your code. You could have something like:

            @
            MyThread::run()
            {
            // do something
            if(m_bStopThread)
            return;
            // do something
            if(m_bStopThread)
            return;
            // do something
            if(m_bStopThread)
            return;
            // do something
            if(m_bStopThread)
            return;
            }

            MyThreda::StopThread()
            {
            m_bStopThread = true;
            }
            @

            Nokia Certified Qt Specialist.
            Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

            1 Reply Last reply
            0
            • T Offline
              T Offline
              TheDestroyer
              wrote on last edited by
              #8

              Thank you for your answers, guys!

              @Franzk: QtConcurrent is very limited. It doesn't help my general purposes. I'm more interested in learning QThread.

              @Gerolf: So interestingly, Gerolf, I have the same idea in the code of my first post. Please check the program of my first post. It's a very small program. You can see that I try to use this "stop" idea exactly the same way you mentioned it, but I can't find the place where I have to place the delete thread statement. Whenever I introduce a thread deletion, the program freezes!!!! please take a look at the program code in my first post!

              1 Reply Last reply
              0
              • G Offline
                G Offline
                giesbert
                wrote on last edited by
                #9

                You can use it like this:

                @
                MyMainWnd::beginWork()
                {
                pThread = new MyThread();
                pThread->start();
                }

                MyMainWnd::stop()
                {
                pThread->StopThread()
                pThread->wait();
                delete pThread;
                pThread = 0;
                }
                @

                To use this, you have to ensure, that the stopped checks, will not have a too long time in between...

                Nokia Certified Qt Specialist.
                Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                1 Reply Last reply
                0
                • T Offline
                  T Offline
                  TheDestroyer
                  wrote on last edited by
                  #10

                  Thank you for the reply!

                  I'll try this and tell you how it goes! I tried the command QThread::wait() before, but caused freezing as well. So I'll try it again and come with detailed description of what I get :)

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    andre
                    wrote on last edited by
                    #11

                    It will cause freezing, if the thread doesn't respond quickly to being told to stop.

                    1 Reply Last reply
                    0
                    • F Offline
                      F Offline
                      Franzk
                      wrote on last edited by
                      #12

                      Use the deleteLater() approach. That won't cause you to wait for the thread to be finished. On the other hand, maybe you can come up with a way that will allow you to keep the thread around and not recreate it every time.

                      "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

                      http://www.catb.org/~esr/faqs/smart-questions.html

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        andre
                        wrote on last edited by
                        #13

                        I would not call deleteLater on a QThread that is still running. Sounds like a recipe for all kinds of funny things to happen when you don't expect it.

                        Edit:
                        What might be a good approach, is something like this:
                        @
                        connect(myThread, SIGNAL(finished()), myThread, SLOT(deleteLater()));
                        myThread->stopThisThread();
                        myThread = 0;
                        @

                        1 Reply Last reply
                        0
                        • F Offline
                          F Offline
                          Franzk
                          wrote on last edited by
                          #14

                          [quote author="Andre" date="1307457203"]I would not call deleteLater on a QThread that is still running. Sounds like a recipe for all kinds of funny things to happen when you don't expect it.[/quote]

                          Neither would I. I was referring to what I've stated earlier:
                          @connect(myThread, SIGNAL(finished()), myThread, SLOT(deleteLater()));@

                          Edit: My point exactly :P

                          "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

                          http://www.catb.org/~esr/faqs/smart-questions.html

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            andre
                            wrote on last edited by
                            #15

                            Ah, sorry, missed your previous suggestion for the same idea. I would put the connect call before the stop call though. Otherwise, you might get into a race condition where the thread is already stopped before the connection has been made. Then again, you should probably make the connection at creation time for the thread anyway, not when you want to stop it.

                            1 Reply Last reply
                            0
                            • G Offline
                              G Offline
                              giesbert
                              wrote on last edited by
                              #16

                              [quote author="Andre" date="1307457203"]I would not call deleteLater on a QThread that is still running. Sounds like a recipe for all kinds of funny things to happen when you don't expect it.

                              Edit:
                              What might be a good approach, is something like this:
                              @
                              connect(myThread, SIGNAL(finished()), myThread, SLOT(deleteLater()));
                              myThread->stopThisThread();
                              myThread = 0;
                              @

                              [/quote]

                              This can also lead to unexpected behavior. You call delete in the main thread when the event loop comes to this point. While it reaches this, the thread could be suspended (depends on timing) or be finished, even if the emit is the last command in the run method.

                              EDIT:

                              So you would need a wait in the destructor of the thread….

                              Nokia Certified Qt Specialist.
                              Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                andre
                                wrote on last edited by
                                #17

                                Gerolf, you mean that QThread::finished() may be emitted before the thread is actually finished? That would be a bug, would it not?

                                1 Reply Last reply
                                0
                                • F Offline
                                  F Offline
                                  Franzk
                                  wrote on last edited by
                                  #18

                                  From reading the QThread sources it seems on symbian, the finished() signal is emitted from the threaded function (after run() returns). On unix, the signal is emitted in the pthread cleanup handler. Didn't check the windows code. It seems Gerolf could have a point here. However, if that is the case, the only way to check if the thread is actually still running is by using some pthread_kill() magic.

                                  "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

                                  http://www.catb.org/~esr/faqs/smart-questions.html

                                  1 Reply Last reply
                                  0
                                  • G Offline
                                    G Offline
                                    giesbert
                                    wrote on last edited by
                                    #19

                                    [quote author="Andre" date="1307457823"]Gerolf, you mean that QThread::finished() may be emitted before the thread is actually finished? That would be a bug, would it not?[/quote]

                                    The point is: when is a thread finished?

                                    To emit a signal, you need code. This code is somewhere :-) If it is inside the threads function (even it is outside run()) you might get in timing problems.

                                    Nokia Certified Qt Specialist.
                                    Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                                    1 Reply Last reply
                                    0
                                    • A Offline
                                      A Offline
                                      andre
                                      wrote on last edited by
                                      #20

                                      I get that, and judging by Franzks analysis, you have a point at least in the Symbian case. It seems logical to me that Qts implementation would make sure the thread really has terminated before the signal is emitted. I understand that you need code to do the emit, but that code does not belong in the thread who's termination it is supposed to signal. That would mean that the Symbian implementation is wrong, but I have no idea if it is possible to do it the right way on that platform.

                                      1 Reply Last reply
                                      0
                                      • G Offline
                                        G Offline
                                        giesbert
                                        wrote on last edited by
                                        #21

                                        I even don't know if that is possible on windows.
                                        But the Qt code does not guarantee that.
                                        This is an excerpt of QThread for windows:

                                        @
                                        unsigned int __stdcall QThreadPrivate::start(void *arg)
                                        {
                                        // some initialization

                                        emit thr->started();
                                        
                                        thr->run();
                                        
                                        finish(arg);
                                        return 0;
                                        

                                        }

                                        void QThreadPrivate::finish(void *arg, bool lockAnyway)
                                        {
                                        // some other stuff
                                        emit thr->finished();
                                        // some other stuff
                                        }

                                        void QThread::start(Priority priority)
                                        {
                                        // some other stuff
                                        d->handle = (Qt::HANDLE) _beginthreadex(NULL, d->stackSize, QThreadPrivate::start,
                                        this, CREATE_SUSPENDED, &(d->id));

                                        // some other stuff
                                        

                                        }
                                        @

                                        This means, the thread function QThreadPrivate::start defines the thread. When it is finished, the thread dies. Within this method, the finished signal is emitted and it is not at the very end of the thread, but guaranteed after the run method....

                                        I'm not sure, whether there is a thread stopped signal on windows...

                                        Nokia Certified Qt Specialist.
                                        Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                                        1 Reply Last reply
                                        0
                                        • F Offline
                                          F Offline
                                          Franzk
                                          wrote on last edited by
                                          #22

                                          Apparently the windows thread performs exactly the same action as the symbian implementation. The linux implementation does pretty much the same when no pthread_cancel() is used. The cleanup function is called by a pthread_cleanup_pop(1); This is likely to happen within the thread though. Anyway, this being known, the solution would rather go towards

                                          @connect(t, SIGNAL(finished()), this, SLOT(cleanupThread()));
                                          ...
                                          void This::cleanupThread()
                                          {
                                          thread->wait();
                                          thread->deleteLater();
                                          }@
                                          provided of course that wait() is guaranteed to wait until the OS thread is actually finished. Details are different, but the general idea is still the same.

                                          "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

                                          http://www.catb.org/~esr/faqs/smart-questions.html

                                          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