LINUX.ORG.RU

Запуск внешней программы (процесса) с возможностью остановить по желанию запускающего Си/Си++

 , ,


0

1

Сабж.

Полезно было бы еще получать pid. Запускаемые процессы могут быть любыми. Узнавать о том что запускаемый процесс сам закрылся – архиважно.

system() блокируется и для получения pid-а придется городить уродство с запуском через баш прослойку

В общем, уверен, все занют как сделать красиво, только мне не рассказывают

★★★★★

Эм…

Полезно было бы еще получать pid.

fork() возвращает PID.

с возможностью остановить по желанию

kill() отправит нужный сингнал.

Узнавать о том что запускаемый процесс сам закрылся

waitpid() расскажет, почему процесс закрылся.

Но в общем случае ты не отличишь «процесс самостоятельно закрылся, потому что сам захотел» и «процесс самостоятельно закрылся, потому что ты его попросил». Разве что процесс не будет обрабатывать SIGTERM/SIGINT и мгновенно умирает. Иначе запускаемый процесс должен сам как-то отчитываться, что закрывается по такой-то причине.

ilammy ★★★
()
Ответ на: комментарий от ilammy

fork() возвращает PID.

я чужую программу запускать хочу. Ну типа system(«ping ya.ru -c 100»)

kill() отправит нужный сингнал.

Кому? pid надо. Ну допустим у меня в отдельном потоке висит sustem() и ждет завершения, то есть я узнаю, когда оно завершится, а если я захочу кильнуть из основного потока раньше? Нужен пид

pihter ★★★★★
() автор топика
Ответ на: комментарий от bhfq

используй QtCore, QProcess.

Сильно жирно в моем случае. А оно как делает? Как-то же это сделено на системных вызовах

pihter ★★★★★
() автор топика
Ответ на: комментарий от bhfq

хотя в Poco есть Process который, вроде, умеет все что я хочу. Так я скорее всего и сделаю. Не понятно как такое на сях сдалать, а ведь явно как-то можно :)

pihter ★★★★★
() автор топика
Ответ на: комментарий от pihter

Не понятно как такое на сях сдалать

Завите того самого анонима…

Каштан.

anonymous
()
Ответ на: комментарий от anonymous

глупости про жирно не надо

это дискуссионный вопрос: тащить весь буст ради такой ерунды… да и, собсна, решение я уже нашел, интересно просто как оно под капотом сделано

pihter ★★★★★
() автор топика
Ответ на: комментарий от pihter

тащить весь буст ради такой ерунды

А весь и не надо, не тупи. А что жирне конкретно boost-system (или как оно там) или вон что ты нашёл - это вопрос.

Тем более, что boost весьма приближен к C++. Многое вообще от туда и идёт потом в C++.

А вот с тем, что ты нашёл - ты будешь одарённый весь такой.

Каштан.

anonymous
()
Ответ на: комментарий от pihter

я чужую программу запускать хочу. Ну типа system(«ping ya.ru -c 100»)

сначала fork(), потом exec() с бинарником чужой программы в виде одного из аргументов

Harald ★★★★★
()
Ответ на: комментарий от PPP328

Тебе уже выше написали, что fork .

ну и че, форк вернет пид вновь-созданного-процесса-почти-копии-текущего, а я внешний вызываю: ты можешь форком вызвать пинг и получить его пид?

pihter ★★★★★
() автор топика
Ответ на: комментарий от Harald

сначала fork(), потом exec() с бинарником чужой программы в виде одного из аргументов

о, а че, так можно было? :) оч любопытно, надо попробовать

pihter ★★★★★
() автор топика

там ещё куча нюансов разных, открытые файловые дескрипторы от родительского процесса могут наследоваться и всё такое

Harald ★★★★★
()
Ответ на: комментарий от Harald

что-то при слове «boost» ты так не возбудился, хотя там тоже понапихано в заголовочники.

По вопросу - у владельца репы довольно расписанный профиль. Даже фотка есть.

anonymous
()
Ответ на: комментарий от Harald

Частая практика для C++

Каштан.

anonymous
()
Ответ на: комментарий от anonymous

что-то при слове «boost» ты так не возбудился, хотя там тоже понапихано в заголовочники.

так то С++, там так принято, и там это всё равно шаблоны, объявление кода инстанциируется в том файле, откуда этот заголовочник заинклудили

https://github.com/sheredom/subprocess.h/issues/47

аффтар явно упоротый

Harald ★★★★★
()
Ответ на: комментарий от pihter

fork возвращает 0 в порожденный процесс и pid в родительский. Вот отсюда и танцуй.

pinus_nigra
()
Ответ на: комментарий от pihter

я чужую программу запускать хочу. Ну типа system(«ping ya.ru -c 100»)

pipe() + fork() + execve() = system()

Вот тебе простой пример: https://github.com/dim13/redbutton/blob/master/cmd/c/redbutton.c

void
go(char *script, char *action)
{
	int status;

	switch(fork()) {
	case -1:
		err(1, "fork");
		/* NOTREACHED */
	case 0:
		execl(script, script, action, NULL);
		/* NOTREACHED */
	default:
		wait(&status);	
		if (WEXITSTATUS(status) != 0)
			warnx("child failed");
		break;
	}
}
beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 4)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <unistd.h>
#include <spawn.h>
#include <sys/wait.h>

extern char **environ;

void run_cmd(char *cmd)
{
    pid_t pid;
    char *argv[] = {"sh", "-c", cmd, NULL};
    int status;
    printf("Run command: %s\n", cmd);
    status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ);
    if (status == 0) {
        printf("Child pid: %i\n", pid);
        if (waitpid(pid, &status, 0) != -1) {
            printf("Child exited with status %i\n", status);
        } else {
            perror("waitpid");
        }
    } else {
        printf("posix_spawn: %s\n", strerror(status));
    }
}

int main(int argc, char* argv[])
{
    run_cmd(argv[1]);
    return 0;
}

Не благодари.

Djanik
()
Ответ на: комментарий от pihter

А как ты думаешь это делает командная оболочка, нет дружок, это снова в школу… На Ютубе есть хорошие лекции по устройству юникса на примере линукса от ИТМО, посмотри тебе не повредит или узнать что-то новое или освежить явно забытое.

anonymous
()
man 3 posix_spawn
anonymous
()
Ответ на: комментарий от pihter

это вообще единственный способ запуска процессов, все остальное - это надстройки на вызовами fork + exec

EugeneBas ★★
()
Ответ на: комментарий от pihter

о, а че, так можно было? :) оч любопытно, надо попробовать

из man fork

After a fork() in a multithreaded program, the child can
safely call only async-signal-safe functions (see
signal-safety(7)) until such time as it calls execve(2).

С fork() будь осторожен. Между fork() и execve() можно использовать только async-signal-safe функции.

К сожалению fork() - это из тех прекрасных мест, где можно себе выстрелить в ногу.

Может быть более целесообразно использовать готовую либу, чем писать все самому.

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

Может быть более целесообразно использовать готовую либу, чем писать все самому.

Вне всяких сомнений, так и сделаю. К тому же накидали уже всем миром 5 решений. Просто не понятно было как оно на системных вызовах работает, теперь понятно

pihter ★★★★★
() автор топика
Ответ на: комментарий от pihter

Прочёл тему и комменты.

К тому же накидали уже всем миром 5 решений.

Думаю не 5, а 6. По какой-то странной причине уважаемые коллеги забыли парочку popen()/pclose(). https://man7.org/linux/man-pages/man3/popen.3.html Хорошая вещь, если нужно запустить приложение, открыть с ней канал и читать оттуда/писать туда что-либо.

Moisha_Liberman ★★
()

fork()+exec()+обработка sig_chld или waitpid() О том как закончился процесс можно погадать по коду завершения, но они специфичны для конкретного приложения

З.ы. прежде чем во все это нырять погугли про утечки файловых дескрипторов и поделай с этим что-то

cobold ★★★★★
()
Последнее исправление: cobold (всего исправлений: 1)

Узнавать о том что запускаемый процесс сам закрылся – архиважно.

Если твоя управляющая программа принудительно не убивала, то процесс закрылся сам, или под действием сверхестественных неконтролируемых твоей программой сил неотличимых от самоубийства.

anonymous
()
Ответ на: комментарий от pihter

QtCore жирно, а Poco - нет, понял. Сорцы же открытые, берешь да читаешь реализацию функций. 😱

bhfq ★★★★★
()
Последнее исправление: bhfq (всего исправлений: 1)
Ответ на: комментарий от pihter

о, а че, так можно было? :) оч любопытно, надо попробовать

Кстати, каноничная реализация system() на unix-системах это как раз fork-exec-wait

annulen ★★★★★
()
Последнее исправление: annulen (всего исправлений: 1)
Ответ на: комментарий от Aswed

Есть еще модный молодежный posix_spawn, который внутри может использовать vfork вместо fork

annulen ★★★★★
()
Ответ на: комментарий от annulen

вот да. я вообще не понимаю, чем тут ТС страдает. в любой обёртке это будут те же самые яйца, только плюс-минус разные ненужные довески вокруг и ещё дополнительные библиотеки. получить реальную причину закрытия процесса, если он сам как-то об этом не сообщает, невозможно. есть код завершения и всё. если там есть информация о том, почему он закрылся, то его можно анализировать. если нет - то никак.

Iron_Bug ★★★★★
()
Ответ на: комментарий от Iron_Bug

Чета, боюсь, меня неправильно поняли: мне важно узнавать именно о факте закрытия, а не о том что сам он или не сам. Причина мне не важна. Понятно, что о факте узнавать проблем нет

pihter ★★★★★
() автор топика

Запускай в gdb в режиме отладки.

xmikex ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.