Запуск второй программы Linux и выход из текущей из C/C++?

Возможно ли из программы Linux на C или C++ (скажем, /usr/bin/foo) программно запустить другую программу (скажем, /usr/bin/bar) и нормально завершить foo, а bar продолжить работу?

system(3) не подходит, так как блокируется до завершения другой программы. Я хотел бы что-то, что возвращается немедленно.

Обе программы являются программами с графическим интерфейсом, но я подозреваю, что это не имеет значения.

Есть ли что-нибудь в Qt или boost::process, что может помочь?

Есть ли какая-нибудь обычная программа-оболочка Linux, которую я мог бы запустить через system(3) для достижения этой цели? Я пробовал xdg-open, но не думаю, что это правильно.

По сути, я хочу, чтобы вторая программа отделялась от первой и вела себя так, как если бы пользователь запускал ее через системный пользовательский интерфейс. (Например, в MacOS есть команда open, поэтому она будет похожа на system("open /usr/bin/bar"))


person Andrew Tomazos    schedule 02.12.2020    source источник
comment
Комбинация fork() и execv() - это то, как это обычно делается. Кроме того, вы можете system() с & в конце, чтобы работать в фоновом режиме, но это противно.   -  person SergeyA    schedule 02.12.2020
comment
Поскольку вы упомянули boost::process, вы можете взглянуть на boost::process::spawn или класс boost::process::child, который позволяет настроить и создать дочерний процесс перед отсоединив его.   -  person G.M.    schedule 02.12.2020
comment
Поскольку вы упомянули Qt, есть QProcess::start, который делает это.   -  person rustyx    schedule 02.12.2020
comment
@rustyx: Мы уверены, что родительский процесс может завершиться, в то время как процесс, запущенный с QProcess::start, продолжает работать?   -  person Andrew Tomazos    schedule 02.12.2020
comment
@rustyx: Может быть, QProcess::startDetached выглядит правильно.   -  person Andrew Tomazos    schedule 02.12.2020


Ответы (2)


С Qt вы можете использовать bool QProcess::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory = QString(), qint64 *pid = nullptr), как описано здесь https://doc.qt.io/qt-5/qprocess.html#startDetached

Вот минимальный пример того, как его использовать:

#include <QCoreApplication>
#include <QProcess>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    /*
     * starting netstat with args
     * in case the main event loop is exited
     * netstat will be parented to init ( pid 1 ) and continue running
     */
    QProcess::startDetached("/bin/netstat", QStringList() << "-pla" << "-ntuc");

    return a.exec();
}
person Fryz    schedule 02.12.2020

Классический способ — использование Fork-Exec: https://en.wikipedia.org/wiki/Fork%E2%80%93exec, который доступен в любой производной от Unix ОС, включая Linux. Не нужно добавлять какую-либо библиотеку, фреймворк и т.д.

person cpp19    schedule 03.12.2020
comment
В итоге я использовал QProcess::startDetached, но я уверен, что под капотом он просто делает fork-exec, как вы предлагаете. - person Andrew Tomazos; 03.12.2020