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. The difference between QProcess::start() and QProcess::startDetached() for the called application itself

The difference between QProcess::start() and QProcess::startDetached() for the called application itself

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 3 Posters 8.0k Views
  • 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.
  • A Offline
    A Offline
    Andrey Vasilyev
    wrote on last edited by
    #1

    What is the difference in using QProcess::start () and QProcess::startDetached () for the called application itself?
    I observe the different behavior of the called application when using these methods. I call avrdude.exe with some arguments and the result differs when using the QProcess :: start(), while the result of the work QProcess :: startDetached() is exactly the same as if I used avrdude.exe directly. Why is this happening?

    JonBJ 1 Reply Last reply
    0
    • BuckwheatB Offline
      BuckwheatB Offline
      Buckwheat
      wrote on last edited by
      #2

      @Andrey-Vasilyev said in The difference between QProcess::start() and QProcess::startDetached() for the called application itself:

      ents and the result differs when using the QProcess :: start(), while the result of the work QProcess :: startDetached() is exactly the same as if I used avrdude.exe directly. Why is this

      Hi @Andrey-Vasilyev and Welcome!

      First, from the Qt5.11 docs for startDetached:
      "Starts the program set by setProgram() with arguments set by setArguments() in a new process, and detaches from it. Returns true on success; otherwise returns false. If the calling process exits, the detached process will continue to run unaffected.

      Unix: The started process will run in its own session and act like a daemon.

      The process will be started in the directory set by setWorkingDirectory(). If workingDirectory() is empty, the working directory is inherited from the calling process.

      Note: On QNX, this may cause all application threads to temporarily freeze.

      If the function is successful then *pid is set to the process identifier of the started process. Note that the child process may exit and the PID may become invalid without notice. Furthermore, after the child process exits, the same PID may be recycled and used by a completely different process. User code should be careful when using this variable, especially if one intends to forcibly terminate the process by operating system means."

      What this really means, is that it is not in your control or in your process tree. Your application can end and a QProcess started with startDetached will continue to stay running. All other aspects of QProcess should still work the same.

      Using startDetached is great if you want to start tasks that you wish to keep running after you exit. Just note that the process-id returned can be re-used by the OS so it is not good to use just that to manage your tasks.

      Dave Fileccia

      A 1 Reply Last reply
      1
      • A Andrey Vasilyev

        What is the difference in using QProcess::start () and QProcess::startDetached () for the called application itself?
        I observe the different behavior of the called application when using these methods. I call avrdude.exe with some arguments and the result differs when using the QProcess :: start(), while the result of the work QProcess :: startDetached() is exactly the same as if I used avrdude.exe directly. Why is this happening?

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

        @Andrey-Vasilyev
        One thing which differs is that the called program does not inherit its i/o file descriptors from the calling program, and redirected from/to it, which is normally what happens from start(). I haven't looked, but startDetached() processes are likely to have no initial stdin/stdout/stderr, and won't inherit a console if called from there. That might affect the behaviour you are seeing.

        The called process is not terminated if the calling process exits. But I don't see why that would be likely to produce the difference you see.

        There will be further OS-specific differences.

        Is your avrdude.exe a console or UI application? For example, if it's expecting its stdin to be coming from a terminal, it will be disappointed...

        1 Reply Last reply
        1
        • BuckwheatB Buckwheat

          @Andrey-Vasilyev said in The difference between QProcess::start() and QProcess::startDetached() for the called application itself:

          ents and the result differs when using the QProcess :: start(), while the result of the work QProcess :: startDetached() is exactly the same as if I used avrdude.exe directly. Why is this

          Hi @Andrey-Vasilyev and Welcome!

          First, from the Qt5.11 docs for startDetached:
          "Starts the program set by setProgram() with arguments set by setArguments() in a new process, and detaches from it. Returns true on success; otherwise returns false. If the calling process exits, the detached process will continue to run unaffected.

          Unix: The started process will run in its own session and act like a daemon.

          The process will be started in the directory set by setWorkingDirectory(). If workingDirectory() is empty, the working directory is inherited from the calling process.

          Note: On QNX, this may cause all application threads to temporarily freeze.

          If the function is successful then *pid is set to the process identifier of the started process. Note that the child process may exit and the PID may become invalid without notice. Furthermore, after the child process exits, the same PID may be recycled and used by a completely different process. User code should be careful when using this variable, especially if one intends to forcibly terminate the process by operating system means."

          What this really means, is that it is not in your control or in your process tree. Your application can end and a QProcess started with startDetached will continue to stay running. All other aspects of QProcess should still work the same.

          Using startDetached is great if you want to start tasks that you wish to keep running after you exit. Just note that the process-id returned can be re-used by the OS so it is not good to use just that to manage your tasks.

          A Offline
          A Offline
          Andrey Vasilyev
          wrote on last edited by
          #4

          Hi @JonB and @Buckwheat
          Thanks for the response!

          Avrdude.exe is a console application.
          The code below is where I start the process. It does not require input, all the necessary information is passed in the arguments

          void avrdudeHandler::init()
          {
              avrdude = new QProcess;
              avrdude->setProgram(avrdudePath);
              avrdude->setStandardErrorFile("stderr.txt");
              avrdude->setStandardOutputFile("stdout.txt");
              avrdude->setArguments(signatureReading);
              avrdude->start();
              //avrdude->startDetached();
          }
          

          This is the result of the QProcess::start ()

          avrdude.exe: AVR device initialized and ready to accept instructions
          
          Reading | ################################################## | 100% 0.00s
          
          avrdude.exe: Device signature = 0x1e940b (probably m168p)
          
          avrdude.exe done.  Thank you.
          

          And this is the result of the QProcess::startDetached()

          avrdude.exe: AVR device initialized and ready to accept instructions
          
          
          Reading |                                                    | 0% 0.00s
          Reading | #################                                  | 33% 0.00s
          Reading | #################################                  | 66% 0.01s
          Reading | ################################################## | 100% 0.01s
          
          avrdude.exe: Device signature = 0x1e940b (probably m168p)
          
          avrdude.exe: safemode: Fuses OK (E:F9, H:D5, L:F7)
          
          avrdude.exe done.  Thank you.
          

          I'm think that avrdude.exe can't execute one more instance or thread when using QProcess::start ()

          1 Reply Last reply
          0
          • BuckwheatB Offline
            BuckwheatB Offline
            Buckwheat
            wrote on last edited by
            #5

            Hi @Andrey-Vasilyev ,

            I really looks like it is sending "Reading | <some stuff> | <status> <carriage-return>" each time it updates the status and the writer is thinking it is <carriage-return><line-feed> or something. Have you tried reading in the data yourself and inspecting the strings?

            I typically do not write to files but read the data and either update status or log as it goes along.

            Dave Fileccia

            A 1 Reply Last reply
            0
            • BuckwheatB Buckwheat

              Hi @Andrey-Vasilyev ,

              I really looks like it is sending "Reading | <some stuff> | <status> <carriage-return>" each time it updates the status and the writer is thinking it is <carriage-return><line-feed> or something. Have you tried reading in the data yourself and inspecting the strings?

              I typically do not write to files but read the data and either update status or log as it goes along.

              A Offline
              A Offline
              Andrey Vasilyev
              wrote on last edited by
              #6

              @Buckwheat

              Yes, I tried to accept output through qdebug ().

                  avrdude->setProcessChannelMode(QProcess::MergedChannels);
                  connect(avrdude, &QProcess::readyReadStandardOutput, [=](){qDebug() << avrdude->readAllStandardOutput();});
              

              Even when avrdude.exe starts with the -l option for it to store the data into its own log, the situation is the same.

              JonBJ 1 Reply Last reply
              0
              • BuckwheatB Offline
                BuckwheatB Offline
                Buckwheat
                wrote on last edited by
                #7

                Hi @Andrey-Vasilyev ,

                It really looks like a <cr> vs. <cr><lf> issue. What did the trailing chars look like? I am no expert on QProcess inner workings, but I wonder if for some reason, since startDetached acts like a daemon, the standard output cannot determine if it processes end-of-line type sequences properly.

                Is the output in one format or another an issue? If you need to NOT wait for the app, you could always use signals to be notified when the app finishes, etc. (like you did the output) and just use QProcess::start.

                Dave Fileccia

                1 Reply Last reply
                0
                • A Andrey Vasilyev

                  @Buckwheat

                  Yes, I tried to accept output through qdebug ().

                      avrdude->setProcessChannelMode(QProcess::MergedChannels);
                      connect(avrdude, &QProcess::readyReadStandardOutput, [=](){qDebug() << avrdude->readAllStandardOutput();});
                  

                  Even when avrdude.exe starts with the -l option for it to store the data into its own log, the situation is the same.

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

                  @Andrey-Vasilyev
                  I'm not really understanding what your problem is exactly!

                  Is it the fact that some progress output was over one line in one case and 4 lines in the other?

                  Is it that only the startDetached() produces the line:

                  avrdude.exe: safemode: Fuses OK (E:F9, H:D5, L:F7)
                  

                  while the result of the work QProcess :: startDetached() is exactly the same as if I used avrdude.exe directly

                  What does "used avrdude.exe directly" mean? Run it from a command prompt? Run it from Windows Run? Double-click a shortcut? Something else?

                  And your invoking Qt application, what is that? Does it have a UI or is it console?

                  A 1 Reply Last reply
                  0
                  • JonBJ JonB

                    @Andrey-Vasilyev
                    I'm not really understanding what your problem is exactly!

                    Is it the fact that some progress output was over one line in one case and 4 lines in the other?

                    Is it that only the startDetached() produces the line:

                    avrdude.exe: safemode: Fuses OK (E:F9, H:D5, L:F7)
                    

                    while the result of the work QProcess :: startDetached() is exactly the same as if I used avrdude.exe directly

                    What does "used avrdude.exe directly" mean? Run it from a command prompt? Run it from Windows Run? Double-click a shortcut? Something else?

                    And your invoking Qt application, what is that? Does it have a UI or is it console?

                    A Offline
                    A Offline
                    Andrey Vasilyev
                    wrote on last edited by Andrey Vasilyev
                    #9

                    Hi @JonB

                    The problem is in the different behavior of the called process, I'm trying to understand why.
                    And the difference is just this line below, this is what I need from avrude.exe

                    avrdude.exe: safemode: Fuses OK (E:F9, H:D5, L:F7)
                    

                    The result of the QProcess :: startDetached() is correct and coincides with the result of running avrude.exe from the command prompt .
                    My application simply runs an avrdude.exe with different parameters depending on which button you clicked.

                    I think I solved the problem, but did not understand why it was happening at all.
                    When I start the avrdude.exe using QProcess::start() with the -s option in arguments, everything works as it should.
                    Below is the description of the -s option from the avrdude documentation:

                    Disable safemode prompting. When safemode discovers that one or more fuse
                    bits have unintentionally changed, it will prompt for conrmation regarding
                    whether or not it should attempt to recover the fuse bit(s). Specifying this
                    flag disables the prompt and assumes that the fuse bit(s) should be recovered
                    without asking for conrmation rst.
                    

                    As I understand from this description avrdude waiting for confirmation in stdin, and the option -s disables the request for this confirmation.

                    JonBJ 1 Reply Last reply
                    0
                    • A Andrey Vasilyev

                      Hi @JonB

                      The problem is in the different behavior of the called process, I'm trying to understand why.
                      And the difference is just this line below, this is what I need from avrude.exe

                      avrdude.exe: safemode: Fuses OK (E:F9, H:D5, L:F7)
                      

                      The result of the QProcess :: startDetached() is correct and coincides with the result of running avrude.exe from the command prompt .
                      My application simply runs an avrdude.exe with different parameters depending on which button you clicked.

                      I think I solved the problem, but did not understand why it was happening at all.
                      When I start the avrdude.exe using QProcess::start() with the -s option in arguments, everything works as it should.
                      Below is the description of the -s option from the avrdude documentation:

                      Disable safemode prompting. When safemode discovers that one or more fuse
                      bits have unintentionally changed, it will prompt for conrmation regarding
                      whether or not it should attempt to recover the fuse bit(s). Specifying this
                      flag disables the prompt and assumes that the fuse bit(s) should be recovered
                      without asking for conrmation rst.
                      

                      As I understand from this description avrdude waiting for confirmation in stdin, and the option -s disables the request for this confirmation.

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

                      @Andrey-Vasilyev
                      Like I said earlier, the major difference between start() & startDetached() is the state of stdin/out/err file handles on entry to the sub-process, and is the only thing likely to be "noticed by"/affect it.

                      • start(): child's standard I/O descriptors attached to parent (via anonymous pipe). Read http://doc.qt.io/qt-5/qprocess.html#ProcessChannelMode-enum etc. From parent QProcess has methods to write to child's stdin and/or read from child's stdout/err. Child sees these descriptors as open for read/write.

                      • startDetached(): child's standard I/O descriptors not attached to parent . Presumably they are closed (e.g. child read stdin => EOF). Only setStandardInput/Output/ErrorFile() can be used to cause them to read from/write to files.

                      You'd have to understand how this affects your AVR Dude program to know what that would cause it to do, and why some -s argument would address the situation. The stdin situation will doubtless affect its "prompt for confirmation regarding".

                      Purely at a guess, if you want your start() to behave same as your startDetached() for your particular avrdude child try http://doc.qt.io/qt-5/qprocess.html#closeWriteChannel. OTOH, if you want to be able to type in the console where you run your Qt (console) app from and have that go to the sub-process, look at http://doc.qt.io/qt-5/qprocess.html#InputChannelMode-enum and try setting it to QProcess::ForwardedInputChannel.

                      I trust the above clarifies/helps!

                      A 1 Reply Last reply
                      3
                      • JonBJ JonB

                        @Andrey-Vasilyev
                        Like I said earlier, the major difference between start() & startDetached() is the state of stdin/out/err file handles on entry to the sub-process, and is the only thing likely to be "noticed by"/affect it.

                        • start(): child's standard I/O descriptors attached to parent (via anonymous pipe). Read http://doc.qt.io/qt-5/qprocess.html#ProcessChannelMode-enum etc. From parent QProcess has methods to write to child's stdin and/or read from child's stdout/err. Child sees these descriptors as open for read/write.

                        • startDetached(): child's standard I/O descriptors not attached to parent . Presumably they are closed (e.g. child read stdin => EOF). Only setStandardInput/Output/ErrorFile() can be used to cause them to read from/write to files.

                        You'd have to understand how this affects your AVR Dude program to know what that would cause it to do, and why some -s argument would address the situation. The stdin situation will doubtless affect its "prompt for confirmation regarding".

                        Purely at a guess, if you want your start() to behave same as your startDetached() for your particular avrdude child try http://doc.qt.io/qt-5/qprocess.html#closeWriteChannel. OTOH, if you want to be able to type in the console where you run your Qt (console) app from and have that go to the sub-process, look at http://doc.qt.io/qt-5/qprocess.html#InputChannelMode-enum and try setting it to QProcess::ForwardedInputChannel.

                        I trust the above clarifies/helps!

                        A Offline
                        A Offline
                        Andrey Vasilyev
                        wrote on last edited by Andrey Vasilyev
                        #11

                        Thanks @JonB !
                        Your advice was very helpful

                        The source code of avrdude.exe contains a line of code:

                          if (isatty(STDIN_FILENO) == 0 && silentsafe == 0)
                            safemode  = 0;       /* Turn off safemode if this isn't a terminal */
                        

                        silentsafe depends on -s argument, and the function isatty(STDIN_FILENO) always returns 0 when process started using QProcess::start(), because of child's standard I/O descriptors attached to parent via pipe.
                        Below is the description of this function:

                        The `int isatty(int fildes)`  function shall test whether fildes, an open file descriptor, is associated with a terminal device.
                        
                        JonBJ 1 Reply Last reply
                        1
                        • A Andrey Vasilyev

                          Thanks @JonB !
                          Your advice was very helpful

                          The source code of avrdude.exe contains a line of code:

                            if (isatty(STDIN_FILENO) == 0 && silentsafe == 0)
                              safemode  = 0;       /* Turn off safemode if this isn't a terminal */
                          

                          silentsafe depends on -s argument, and the function isatty(STDIN_FILENO) always returns 0 when process started using QProcess::start(), because of child's standard I/O descriptors attached to parent via pipe.
                          Below is the description of this function:

                          The `int isatty(int fildes)`  function shall test whether fildes, an open file descriptor, is associated with a terminal device.
                          
                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by JonB
                          #12

                          @Andrey-Vasilyev
                          Yes, I expected your avrdude.exe child to be using isatty(0) to decide whether to prompt interactively or not. But I would have expected startDetached()'s stdin to be closed, if anything, and therefore not isatty(0) too, so not sure why that is differing for what you see under start(). However, the overall is it's probably just the difference in stdin which is somehow producing the different behaviour from AVR dude guy.

                          It should be the case that when choosing between them: if you want "nothing to do" with the child, use startDetached(); if you have something to do with it, like communicating with it or waiting for it to finish, use start().

                          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