The difference between QProcess::start() and QProcess::startDetached() for the called application itself
-
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? -
@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.
-
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?@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 fromstart()
. I haven't looked, butstartDetached()
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... -
@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.
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 argumentsvoid 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 ()
-
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.
-
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.
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.
-
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.
-
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.
@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?
-
@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?
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.exeavrdude.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 thecommand 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 theavrdude.exe
usingQProcess::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 conrmation 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 conrmation rst.
As I understand from this description avrdude waiting for confirmation in stdin, and the option
-s
disables the request for this confirmation. -
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.exeavrdude.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 thecommand 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 theavrdude.exe
usingQProcess::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 conrmation 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 conrmation rst.
As I understand from this description avrdude waiting for confirmation in stdin, and the option
-s
disables the request for this confirmation.@Andrey-Vasilyev
Like I said earlier, the major difference betweenstart()
&startDetached()
is the state ofstdin/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 parentQProcess
has methods to write to child'sstdin
and/or read from child'sstdout/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 readstdin
=>EOF
). OnlysetStandardInput/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. Thestdin
situation will doubtless affect its "prompt for confirmation regarding".Purely at a guess, if you want your
start()
to behave same as yourstartDetached()
for your particularavrdude
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 toQProcess::ForwardedInputChannel
.I trust the above clarifies/helps!
-
-
@Andrey-Vasilyev
Like I said earlier, the major difference betweenstart()
&startDetached()
is the state ofstdin/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 parentQProcess
has methods to write to child'sstdin
and/or read from child'sstdout/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 readstdin
=>EOF
). OnlysetStandardInput/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. Thestdin
situation will doubtless affect its "prompt for confirmation regarding".Purely at a guess, if you want your
start()
to behave same as yourstartDetached()
for your particularavrdude
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 toQProcess::ForwardedInputChannel
.I trust the above clarifies/helps!
Thanks @JonB !
Your advice was very helpfulThe 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 functionisatty(STDIN_FILENO)
always returns 0 when process started usingQProcess::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.
-
-
Thanks @JonB !
Your advice was very helpfulThe 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 functionisatty(STDIN_FILENO)
always returns 0 when process started usingQProcess::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.
@Andrey-Vasilyev
Yes, I expected youravrdude.exe
child to be usingisatty(0)
to decide whether to prompt interactively or not. But I would have expectedstartDetached()
'sstdin
to be closed, if anything, and therefore notisatty(0)
too, so not sure why that is differing for what you see understart()
. However, the overall is it's probably just the difference instdin
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, usestart()
.