Starting second wsl QProcess kills the first one
-
I want to use a Windows Qt program to manage processes in wsl. Each process should be running in the background for some time.
After some trials, I find starting second QProcess will kill the first one. This only happens when running wsl processes.#include <QApplication> #include <QBoxLayout> #include <QLabel> #include <QMetaEnum> #include <QProcess> #include <QPushButton> #include <QWidget> using namespace Qt::StringLiterals; template <typename E> const char *EnumToString(E enumValue) { return QMetaEnum::fromType<E>().valueToKey(int(enumValue)); } struct ProcessCtrl : QWidget { QHBoxLayout lout{this}; QLabel lbState; QPushButton btnKill{u"Kill"_s}; QPushButton btnStart{u"Start"_s}; QProcess process; ProcessCtrl() { lout.addWidget(&lbState); lout.addWidget(&btnKill); lout.addWidget(&btnStart); connect(&btnKill, &QPushButton::clicked, &process, &QProcess::kill); connect(&btnStart, &QPushButton::clicked, [this] { process.start("wsl", QStringList{"-e", "sleep", "5s"}); // `wsl -e` execute the following cmd in wsl without entering wsl shell // `sleep 5s` sleeps for 5 seconds }); connect(&process, &QProcess::stateChanged, [this](QProcess::ProcessState state) { lbState.setText(QString{EnumToString(state)}); }); lbState.setText(QString{EnumToString(process.state())}); } }; struct Widget : QWidget { QVBoxLayout lout{this}; ProcessCtrl ctrl1; ProcessCtrl ctrl2; Widget() { lout.addWidget(&ctrl1); lout.addWidget(&ctrl2); } }; int main(int argc, char **argv) { QApplication a{argc, argv}; Widget w; w.show(); return a.exec(); }
In this demo application, if the first
Start
button is clicked, the first process will run for 5 seconds. If the secondStart
button is clicked during the period, both the first and the second process will exit immediately.I'm using Qt 6.8.2 in Windows 10.
-
@mjs225
My thought is same as @Christian-Ehrlicher's.QProcess
does nothing special other than launching processes. Is thiswsl
behaviour to only allow one instance?On another note. I don't think this will affect your current issue, but think twice before ever using a
connect()
with 3 arguments and a lambda for the slot. There are problems about when the slot should disappear and be disconnected (there was a topic here a few weeks ago where this reared its head). Consider changing to the standard 4 arguments and specify a context object for the slot, probablythis
in your case.@JonB You're right. I always launch one wsl process in one
cmd
window, and wsl processes in different cmd windows can live with each other. Now I tried launching multiple wsl processes in onecmd
usingstart /b
, the result is the same as this demo application: all wsl processes will exit immediately.
So the problem is multiple wsl processes cannot be launched by a single parent. It has nothing to do with QProcess. -
I don't have wsl here but it is working with a simple cmd.exe
Did you try it from the command line if it works? -
I want to use a Windows Qt program to manage processes in wsl. Each process should be running in the background for some time.
After some trials, I find starting second QProcess will kill the first one. This only happens when running wsl processes.#include <QApplication> #include <QBoxLayout> #include <QLabel> #include <QMetaEnum> #include <QProcess> #include <QPushButton> #include <QWidget> using namespace Qt::StringLiterals; template <typename E> const char *EnumToString(E enumValue) { return QMetaEnum::fromType<E>().valueToKey(int(enumValue)); } struct ProcessCtrl : QWidget { QHBoxLayout lout{this}; QLabel lbState; QPushButton btnKill{u"Kill"_s}; QPushButton btnStart{u"Start"_s}; QProcess process; ProcessCtrl() { lout.addWidget(&lbState); lout.addWidget(&btnKill); lout.addWidget(&btnStart); connect(&btnKill, &QPushButton::clicked, &process, &QProcess::kill); connect(&btnStart, &QPushButton::clicked, [this] { process.start("wsl", QStringList{"-e", "sleep", "5s"}); // `wsl -e` execute the following cmd in wsl without entering wsl shell // `sleep 5s` sleeps for 5 seconds }); connect(&process, &QProcess::stateChanged, [this](QProcess::ProcessState state) { lbState.setText(QString{EnumToString(state)}); }); lbState.setText(QString{EnumToString(process.state())}); } }; struct Widget : QWidget { QVBoxLayout lout{this}; ProcessCtrl ctrl1; ProcessCtrl ctrl2; Widget() { lout.addWidget(&ctrl1); lout.addWidget(&ctrl2); } }; int main(int argc, char **argv) { QApplication a{argc, argv}; Widget w; w.show(); return a.exec(); }
In this demo application, if the first
Start
button is clicked, the first process will run for 5 seconds. If the secondStart
button is clicked during the period, both the first and the second process will exit immediately.I'm using Qt 6.8.2 in Windows 10.
@mjs225
My thought is same as @Christian-Ehrlicher's.QProcess
does nothing special other than launching processes. Is thiswsl
behaviour to only allow one instance?On another note. I don't think this will affect your current issue, but think twice before ever using a
connect()
with 3 arguments and a lambda for the slot. There are problems about when the slot should disappear and be disconnected (there was a topic here a few weeks ago where this reared its head). Consider changing to the standard 4 arguments and specify a context object for the slot, probablythis
in your case. -
@mjs225
My thought is same as @Christian-Ehrlicher's.QProcess
does nothing special other than launching processes. Is thiswsl
behaviour to only allow one instance?On another note. I don't think this will affect your current issue, but think twice before ever using a
connect()
with 3 arguments and a lambda for the slot. There are problems about when the slot should disappear and be disconnected (there was a topic here a few weeks ago where this reared its head). Consider changing to the standard 4 arguments and specify a context object for the slot, probablythis
in your case.@JonB You're right. I always launch one wsl process in one
cmd
window, and wsl processes in different cmd windows can live with each other. Now I tried launching multiple wsl processes in onecmd
usingstart /b
, the result is the same as this demo application: all wsl processes will exit immediately.
So the problem is multiple wsl processes cannot be launched by a single parent. It has nothing to do with QProcess. -