QProcess and Ctrl-Z + BG on Linux
-
@JonB said in QProcess and Ctrl-Z + BG on Linux:
The OP mentioned nothing about asking the shell to put it into the background after pressing Ctrl+Z.
well, the original post reads
However, if I run it normally, then suspend it using Ctrl-Z and put it in the background, things stop working
% myprogram
Ctrl+Z
bgTo the original question: I understand you send the GUI process in the background, which launches another process via QProcess. Is the sub-process running already when you send the GUI process to the background? If yes, what's the state of it after you sent the GUI process in the background? Is it actually exiting then later on, and just the finished() signal is missing?
A minimal reproducible example might help. I'm not ruling out a Qt defect, as the QProcess logic is sometimes a bit special, but it doesn't seem like a known issue at least...
-
@Sameer , @jsulm , @kkoehne
To make up for my earlier misunderstanding, have tried following standalone code:#include <QApplication> #include <QDebug> #include <QLayout> #include <QObject> #include <QProcess> #include <QPushButton> #include <QWidget> class MyWidget : public QWidget { private: QProcess *proc; public slots: void onClicked() { proc = new QProcess; QObject::connect(proc, &QProcess::started, this, []() { qDebug() << "Process started"; } ); QObject::connect(proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, []() { qDebug() << "Process finished"; } ); proc->start("sleep", { "10"} ); } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); MyWidget w; w.setLayout(new QVBoxLayout); QPushButton *pb = new QPushButton("QProcess"); w.layout()->addWidget(pb); w.show(); QObject::connect(pb, &QPushButton::clicked, &w, &MyWidget::onClicked); return a.exec(); }
Qt 5.15 (I don't have Qt6), Ubuntu 22.04. Run from terminal. Press Ctrl+Z there after launching, then
bg
. Then press the button. I do see in the terminal from the debug outputProcess started
followed byProcess finished
10 seconds later. So it works normally.Suggest you first try this, does it work for you? If it does compare against your code to find a difference.
-
@JonB OP here. My apologies. I didn't have notifications on. So didn't see these useful responses till today.
I am still trying to solve this problem.
To answer your questions- workerProcess is just the name of the QProcess. No threads involved?
- I DO press the button which starts the workerProcess AFTER the suspend/background
- The worker process is doing non UI stuff.
Hope this answers your questions. Desperately seeking help on this.
-
@JonB
I tried your simple example and it works as expected. I see both the started and finished slots being called even after suspending the application with ctrl+Z and putting it in background.However same thing doesn't seem to happen in my code. Unfortunately my code is too complex to put here. But I tried the following experiment.
Where I start my process, I also started a test process similar to your example.
m_testProcess = new QProcess; QObject::connect(m_testProcess, &QProcess::started, this, []() { qDebug() << "m_testProcess started"; } ); QObject::connect(m_testProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, []() { qDebug() << "m_testProcess finished"; } ); m_testProcess->start("sleep", { "1"} );
Before Ctrl-Z + bg, I see both started and finished messages.
After Ctrl-Z + bg, I see the started message but not the finished message.Any idea what might be going on?
-
@SameerK said in QProcess and Ctrl-Z + BG on Linux:
However same thing doesn't seem to happen in my code. Unfortunately my code is too complex to put here.
I think you know the likely response here! If code works in simple case but not in your "complex" case then probably nobody can guess. You really need to comment out swathes of code till you can find where the different behaviour seems to emanate from.
A couple of tests here. I don't know what we will make of the answers, but let's gather the information:
- Where you do your test you say you do this
sleep()
as well as your process. Eliminate your process for a while, just in case that somehow interferes. - Instead of going
bg
after the Ctrl+Z tryfg
instead. Any difference? - When you do not get the
QProcess::finished
signal, useps
to find the current state of the sub-process. Is it running? Suspended? Zombied? Removed from running processes and no longer found? - Attach slot to signal void QProcess::stateChanged(QProcess::ProcessState newState). What state changes do you get?
- When setting off sub-process start a
QTimer
for, say, once per second. Have it report QProcess::ProcessState QProcess::state() const. What state does that repeatedly report?
- Where you do your test you say you do this
-
@JonB said in QProcess and Ctrl-Z + BG on Linux:
These were very useful suggestions.
- Where you do your test you say you do this
sleep()
as well as your process. Eliminate your process for a while, just in case that somehow interferes.
Did this. Still the same result. - Instead of going
bg
after the Ctrl+Z tryfg
instead. Any difference?
Doingfg
insteadbg
produces same result. - When you do not get the
QProcess::finished
signal, useps
to find the current state of the sub-process. Is it running? Suspended? Zombied? Removed from running processes and no longer found?
Shows up as follows withps
- [sleep] <defunct> - Attach slot to signal void QProcess::stateChanged(QProcess::ProcessState newState). What state changes do you get?
I get Starting and Running, nothing afterwards.
Debug: m_runProcess stateChanged - QProcess::Starting
Debug: m_runProcess stateChanged - QProcess::Running
Debug: m_runProcess started - When setting off sub-process start a
QTimer
for, say, once per second. Have it report QProcess::ProcessState QProcess::state() const. What state does that repeatedly report?
Tried this. It reports the process as "Running"
- Where you do your test you say you do this
-
@SameerK said in QProcess and Ctrl-Z + BG on Linux:
Shows up as follows withps - [sleep] <defunct>
Not sure. From what you say I think the
sleep
sub-process has exited but not been waited on by its parent. Qt parent still thinks process is running, hence nofinished
.Really I'm afraid as you know we have demonstrated in a small test program that it behaves OK there. I think you will have to find out what differs in your real program.
-
Yes that's what seems to be happening.
Another thing I discovered. This happens only with an explicit Ctrl+Z.
If I send a SIGSTOP to the main application process from another terminal and then put it into background, things are fine. -
@SameerK
I had meant to mention testing that. That's ridiculous. But again I'm afraid I don't know what it tells us, nor what you can do about it. I reiterate that since it does not happen on my small test program you are going to have to find out what is different in your complex situation, somehow. -
@JonB I went back to your small test program and ran another experiment and now I can get that to fail too!!!
Invoke test application
Ctrl-Z
bg
Press button
Things work fine (Get both started and finished signals)Invoke test application
Press button
Things work fine (Get both started and finished signals)
Ctrl-Z
bg
Press button
Things don't work anymore (Get started signal but no finished signal!!!)Btw, I am using Qt5.12 and on RedHat Enterprise Linux 8.6