#c #boost #process #boost-process
Вопрос:
Я действительно хочу убить процесс, у которого есть pid, поэтому мой код следующий:
pid_t pid = 28880;
boost::process::child process { pid };
std::cout << "Running: " << process.running() << "n";
process.terminate();
Я заметил, однако, что running() всегда возвращает false (независимо от того, какой pid я беру), и, основываясь на исходном коде, затем terminate даже не вызывается.
Копнув немного глубже, кажется, что вызывается функция linux waitpid
. И он всегда возвращает -1 (что означает, что произошла какая-то ошибка, а не 0, что означало бы: Да, процесс все еще запущен).
WIFSIGNALED возвращает 1, а WTERMSIG возвращает 5.
Я что-то здесь делаю не так?
Ответ №1:
Процесс Boost — это библиотека для выполнения (и управления) дочерними процессами. Ваш процесс не является (обязательно) дочерним процессом и не создается boost.
Действительно running()
, не работает, если процесс не подключен. Использование этого конструктора по определению приводит к отдельному процессу.
Это оставляет интересный вопрос, почему этот конструктор существует, но давайте сосредоточимся на этом вопросе.
Отдельные процессы не могут быть объединены или прекращены.
terminate()
Вызов не является оперативным.
Я бы предложил написать логику самостоятельно — код не такой уж сложный (POSIX kill
или TerminateProcess
).
Если вы хотите, вы можете обмануть, используя детали реализации из библиотеки:
#include <boost/process.hpp>
#include <iostream>
namespace bp = boost::process;
int main(int argc, char** argv) {
for (std::string_view arg : std::vector(argv 1, argv argc)) {
bp::child::child_handle pid{std::atoi(arg.data())};
std::cout << "pid " << pid.id();
std::error_code ec;
bp::detail::api::terminate(pid, ec);
std::cout << " killed: " << ec.message() << std::endl;
}
}
С помощью, например
cat amp;
./sotest $!
С принтами
Комментарии:
1. Спасибо за ответ! Я уже задавался вопросом, что процесс отключен (это тоже заметил). Почему его нельзя прикрепить? Я попробую ваш «обман», так как в первую очередь хотел получить повышение для кросс-платформенного решения. Есть ли какая-либо причина, по которой boost не предлагает api для запросов процессов и тому подобного (как и Qt).
2. Твой обман работает! Процесс, который я пытаюсь убить, на самом деле создан boost, но отделен. Чтобы дать некоторый контекст: я пишу сценарий настройки / демонтажа для своей базы данных и сервера для запуска тестов. Для этого CMake требует, чтобы сценарий установки фактически завершился (эта функция настройки является функцией ctest). Поэтому я запускаю дочерний процесс с помощью boost, записываю pid в файл, отсоединяю его. Затем запустите мои тесты, и в процессе демонтажа я прочитаю pid и завершу процесс. Если у вас есть какая-либо лучшая идея / какая-либо библиотека, которая действительно подходит для этой задачи, я был бы рад ее услышать!
3. Как я уже сказал, управление технологическим процессом-это не то, для чего нужен этот процесс. Что плохого в простой отправке сигнала с использованием упомянутых API? Тот факт, что процесс был «создан процессом boost», не имеет значения, когда процесс был создан другим процессом 🙂