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. QThread with control flow
Forum Updated to NodeBB v4.3 + New Features

QThread with control flow

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 4 Posters 872 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.
  • D Offline
    D Offline
    DungeonLords
    wrote on last edited by
    #1

    I make multi-thread console app example

    Usually when time to finish worker thread my code does goto exit_LABEL

    void Worker::run()
    {
        count = 0;
        while(1)
        {
            if(QThread::currentThread()->isInterruptionRequested()){
                goto exit_LABEL;
            }
    
            count++;
            emit sendMessage(m_message);
            qDebug() << m_message << count;
            f1(); //go to function
            QThread::sleep(1); //1 s pause
        }
    exit_LABEL:;
        emit finished();
        qDebug() << "emit finished()";
    }
    

    I add a lot of functions. I decide allow my code finish while waiting. E.g. I want allow to do goto exit_LABEL; from mySleep(). But how I can program it? I try to found any way to control flow... I found only one way: from each function make return some value, return, return to run() - it makes one million return and then in run() I can analysis why return and decide to goto. Looks not good way... Another idea: drop functions and use macros, but looks not ok...

    void mySleep(const quint32 t){
        static quint32 j;
    
        for(quint32 i=0;i<t;i++){
            QThread::sleep(1);
            if(QThread::currentThread()->isInterruptionRequested()){
                qDebug() << "How I can goto exit_LABEL?" << j++;
            }
        }
    }
    
    void f2(){
        mySleep(10);
    }
    
    void f1(){
        mySleep(5);
        f2();
        mySleep(5);
    }
    

    How I can do goto exit_LABEL - like action from mySleep()?

    SGaistS 1 Reply Last reply
    0
    • D DungeonLords

      I make multi-thread console app example

      Usually when time to finish worker thread my code does goto exit_LABEL

      void Worker::run()
      {
          count = 0;
          while(1)
          {
              if(QThread::currentThread()->isInterruptionRequested()){
                  goto exit_LABEL;
              }
      
              count++;
              emit sendMessage(m_message);
              qDebug() << m_message << count;
              f1(); //go to function
              QThread::sleep(1); //1 s pause
          }
      exit_LABEL:;
          emit finished();
          qDebug() << "emit finished()";
      }
      

      I add a lot of functions. I decide allow my code finish while waiting. E.g. I want allow to do goto exit_LABEL; from mySleep(). But how I can program it? I try to found any way to control flow... I found only one way: from each function make return some value, return, return to run() - it makes one million return and then in run() I can analysis why return and decide to goto. Looks not good way... Another idea: drop functions and use macros, but looks not ok...

      void mySleep(const quint32 t){
          static quint32 j;
      
          for(quint32 i=0;i<t;i++){
              QThread::sleep(1);
              if(QThread::currentThread()->isInterruptionRequested()){
                  qDebug() << "How I can goto exit_LABEL?" << j++;
              }
          }
      }
      
      void f2(){
          mySleep(10);
      }
      
      void f1(){
          mySleep(5);
          f2();
          mySleep(5);
      }
      

      How I can do goto exit_LABEL - like action from mySleep()?

      SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @DungeonLords hi,

      You don't and in fact, you don't need that goto statement. Just break the loop.

      As for your sleep function, make it return a Boolean, and use it to do an early return and thus an early break..

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

      D 1 Reply Last reply
      3
      • SGaistS SGaist

        @DungeonLords hi,

        You don't and in fact, you don't need that goto statement. Just break the loop.

        As for your sleep function, make it return a Boolean, and use it to do an early return and thus an early break..

        D Offline
        D Offline
        DungeonLords
        wrote on last edited by
        #3

        @SGaist in my code I have function1() which call f2(), ... f12345(). And every function will return flag? Is there more beautiful way?

        JonBJ SGaistS 2 Replies Last reply
        0
        • D DungeonLords

          @SGaist in my code I have function1() which call f2(), ... f12345(). And every function will return flag? Is there more beautiful way?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @DungeonLords
          No, there is not. You certainly cannot do any kind of goto in C++ which is not local (i.e. label inside same function). This is not BASIC!

          For those functions which genuinely could/need to return an "error" result by all means make them bool. But applying that principle to every single level of function you call is not a good idea, makes code ugly.

          You can alternatively set a "global" (in some sense) flag and test from time to time, exiting functions if necessary. Like your if(QThread::currentThread()->isInterruptionRequested()) does.

          Another possibility is to emit some signal at the bottom level if you have an event loop running somewhere. For example, a Qt UI program does not just stop dead and exit when user presses Close button, rather a signal is emitted, top-level event loop picks it up, cleans up and exits nicely.

          But none of these actually "unwinds the stack", as it is called for exiting from deep nesting. You still have to write code to test occasionally and react. The only way to do that is to use C++ *exceptions", i.e. try ... catch at top level and throw() at bottom level. But beware. This gets nasty with required C++ destruction of objects as their scope is terminated, can leave stuff in a "messy" state. Qt itself chooses not to use C++ exceptions, and I don't know how well it interacts if you put your own in. This answers your requirement but is probably not recommended.

          The real question/answer is: why do you suddenly want to exit/terminate a thread when you are down inside 10 levels of calls? You should look at your architecture/algorithm and avoid such necessity.

          jeremy_kJ 1 Reply Last reply
          1
          • JonBJ JonB

            @DungeonLords
            No, there is not. You certainly cannot do any kind of goto in C++ which is not local (i.e. label inside same function). This is not BASIC!

            For those functions which genuinely could/need to return an "error" result by all means make them bool. But applying that principle to every single level of function you call is not a good idea, makes code ugly.

            You can alternatively set a "global" (in some sense) flag and test from time to time, exiting functions if necessary. Like your if(QThread::currentThread()->isInterruptionRequested()) does.

            Another possibility is to emit some signal at the bottom level if you have an event loop running somewhere. For example, a Qt UI program does not just stop dead and exit when user presses Close button, rather a signal is emitted, top-level event loop picks it up, cleans up and exits nicely.

            But none of these actually "unwinds the stack", as it is called for exiting from deep nesting. You still have to write code to test occasionally and react. The only way to do that is to use C++ *exceptions", i.e. try ... catch at top level and throw() at bottom level. But beware. This gets nasty with required C++ destruction of objects as their scope is terminated, can leave stuff in a "messy" state. Qt itself chooses not to use C++ exceptions, and I don't know how well it interacts if you put your own in. This answers your requirement but is probably not recommended.

            The real question/answer is: why do you suddenly want to exit/terminate a thread when you are down inside 10 levels of calls? You should look at your architecture/algorithm and avoid such necessity.

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

            @JonB said in QThread with control flow:

            The only way to do that is to use C++ *exceptions", i.e. try ... catch at top level and throw() at bottom level. But beware. This gets nasty with required C++ destruction of objects as their scope is terminated, can leave stuff in a "messy" state.

            I was waiting for someone else to introduce this unpleasantness. Thanks! (with a wink and a grin)

            There's also setjmp and longjmp.

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

            JonBJ 1 Reply Last reply
            0
            • jeremy_kJ jeremy_k

              @JonB said in QThread with control flow:

              The only way to do that is to use C++ *exceptions", i.e. try ... catch at top level and throw() at bottom level. But beware. This gets nasty with required C++ destruction of objects as their scope is terminated, can leave stuff in a "messy" state.

              I was waiting for someone else to introduce this unpleasantness. Thanks! (with a wink and a grin)

              There's also setjmp and longjmp.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @jeremy_k
              Well, it's the only way to truly do "non-local gotos with stack unwind" in C++ (per what the OP actually asks about)! And of course it's more common in languages other than C++. My recollection of setjmp/longjmp() is that they work even less well in C++, I think for example that MSVC has a compilation flag (/EH...) you must pass if you want to use them or for other kinds of exceptions generally. And even if they do proper cleanup from C++ point of view, it would not surprise me if they could nonetheless leave your code in a bad state depending on just how the code handles objects, pointers etc.

              jeremy_kJ 1 Reply Last reply
              0
              • JonBJ JonB

                @jeremy_k
                Well, it's the only way to truly do "non-local gotos with stack unwind" in C++ (per what the OP actually asks about)! And of course it's more common in languages other than C++. My recollection of setjmp/longjmp() is that they work even less well in C++, I think for example that MSVC has a compilation flag (/EH...) you must pass if you want to use them or for other kinds of exceptions generally. And even if they do proper cleanup from C++ point of view, it would not surprise me if they could nonetheless leave your code in a bad state depending on just how the code handles objects, pointers etc.

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

                @JonB said in QThread with control flow:

                @jeremy_k
                Well, it's the only way to truly do "non-local gotos with stack unwind" in C++ (per what the OP actually asks about)! And of course it's more common in languages other than C++. My recollection of setjmp/longjmp() is that they work even less well in C++, I think for example that MSVC has a compilation flag (/EH...) you must pass if you want to use them or for other kinds of exceptions generally. And even if they do proper cleanup from C++ point of view, it would not surprise me if they could nonetheless leave your code in a bad state depending on just how the code handles objects, pointers etc.

                Those links are documenting the standardized C++ variants, in the std namespace.
                "On top of C longjmp, C++ std::longjmp has more restricted behavior."

                Yes, they are error prone. Exceptions are too. Locally scoped objects are destructed. Objects allocated with operator new and referenced by a normal pointer are not. Objects referenced via a unique_ptr are, unless the exception occurs between construction and assignment. Enter std::make_unique...

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

                JonBJ 1 Reply Last reply
                0
                • jeremy_kJ jeremy_k

                  @JonB said in QThread with control flow:

                  @jeremy_k
                  Well, it's the only way to truly do "non-local gotos with stack unwind" in C++ (per what the OP actually asks about)! And of course it's more common in languages other than C++. My recollection of setjmp/longjmp() is that they work even less well in C++, I think for example that MSVC has a compilation flag (/EH...) you must pass if you want to use them or for other kinds of exceptions generally. And even if they do proper cleanup from C++ point of view, it would not surprise me if they could nonetheless leave your code in a bad state depending on just how the code handles objects, pointers etc.

                  Those links are documenting the standardized C++ variants, in the std namespace.
                  "On top of C longjmp, C++ std::longjmp has more restricted behavior."

                  Yes, they are error prone. Exceptions are too. Locally scoped objects are destructed. Objects allocated with operator new and referenced by a normal pointer are not. Objects referenced via a unique_ptr are, unless the exception occurs between construction and assignment. Enter std::make_unique...

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #8

                  @jeremy_k
                  I think we are both happy to recommend OP not to introduce "error jumping". Nonetheless, I merely answered as to what would be required in C++. And if it did allow non-local gotos it would have the same "stack & object unwind" problems, and btw see that effect on switch/case statements, which effectively do gotos and hence compiler places restrictions on what you can/cannot do about scope. "Don't shoot me I am only the messenger" ;-)

                  jeremy_kJ 1 Reply Last reply
                  1
                  • JonBJ JonB

                    @jeremy_k
                    I think we are both happy to recommend OP not to introduce "error jumping". Nonetheless, I merely answered as to what would be required in C++. And if it did allow non-local gotos it would have the same "stack & object unwind" problems, and btw see that effect on switch/case statements, which effectively do gotos and hence compiler places restrictions on what you can/cannot do about scope. "Don't shoot me I am only the messenger" ;-)

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

                    @JonB said in QThread with control flow:

                    @jeremy_k
                    I think we are both happy to recommend OP not to introduce "error jumping".

                    Unless I have a non-local goto out of the airplane, I'll agree.

                    Nonetheless, I merely answered as to what would be required in C++. And if it did allow non-local gotos it would have the same "stack & object unwind" problems, and btw see that effect on switch/case statements,

                    Yep. Just another syntax option while measuring out rope.

                    which effectively do gotos and hence compiler places restrictions on what you can/cannot do about scope.

                    You're in danger of drifting into a Duff's device discussion.

                    "Don't shoot me I am only the messenger" ;-)

                    It may be too late for all of us!

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

                    1 Reply Last reply
                    0
                    • D DungeonLords

                      @SGaist in my code I have function1() which call f2(), ... f12345(). And every function will return flag? Is there more beautiful way?

                      SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @DungeonLords said in QThread with control flow:

                      @SGaist in my code I have function1() which call f2(), ... f12345(). And every function will return flag? Is there more beautiful way?

                      What exactly is your application doing ?
                      You seem to have quite a lot of chained functions calls which may be a sign of a too complex architecture especially if you do things in a thread that you want to break early from.
                      Knowing what you do will allow us to better help you.

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

                      D 1 Reply Last reply
                      0
                      • SGaistS SGaist

                        @DungeonLords said in QThread with control flow:

                        @SGaist in my code I have function1() which call f2(), ... f12345(). And every function will return flag? Is there more beautiful way?

                        What exactly is your application doing ?
                        You seem to have quite a lot of chained functions calls which may be a sign of a too complex architecture especially if you do things in a thread that you want to break early from.
                        Knowing what you do will allow us to better help you.

                        D Offline
                        D Offline
                        DungeonLords
                        wrote on last edited by DungeonLords
                        #11

                        @SGaist I try to use replxx which use std::getline() inside... First time getline stops my code, but I make separatly QThread for it... And now I can't finish my QThread...

                        SGaistS 1 Reply Last reply
                        0
                        • D DungeonLords

                          @SGaist I try to use replxx which use std::getline() inside... First time getline stops my code, but I make separatly QThread for it... And now I can't finish my QThread...

                          SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          That library is a tool to implement something. What is that something ?

                          As stated earlier, if we know what you want to achieve, it will be easier to help you either integrate that library in your application or maybe use a different implementation.

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - 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