Ответ
В Linux для отправки сигналов используется системный вызов kill() (из <csignal>). Основной способ:
#include <csignal>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
int main() {
pid_t target_pid = 12345; // PID целевого процесса
// 1. Отправка сигнала завершения (можно перехватить)
if (kill(target_pid, SIGTERM) == -1) {
perror("kill(SIGTERM) failed");
}
// 2. Отправка сигнала, который нельзя игнорировать (SIGKILL)
// kill(target_pid, SIGKILL);
// 3. Отправка сигнала текущему процессу
raise(SIGUSR1); // Эквивалентно kill(getpid(), SIGUSR1)
// 4. Проверка существования процесса (сигнал 0)
if (kill(target_pid, 0) == 0) {
std::cout << "Process " << target_pid << " exists and we have permission." << std::endl;
} else {
if (errno == ESRCH) {
std::cout << "Process does not exist." << std::endl;
} else if (errno == EPERM) {
std::cout << "No permission to send signal." << std::endl;
}
}
return 0;
}
Важные технические детали:
- Права: Чтобы отправить сигнал, ваш процесс должен иметь соответствующие права (обычно быть владельцем процесса или иметь права root).
- SIGKILL (9) и SIGSTOP (19): Эти сигналы не могут быть перехвачены, проигнорированы или заблокированы процессом-получателем.
- Безопасность в многопоточных программах: В многопоточном приложении
kill()отправляет сигнал всему процессу. Чтобы отправить сигнал конкретному потоку, используйтеpthread_kill(). - Более современный C++ интерфейс (C++11): Для управления сигналами внутри программы можно использовать
std::signal, но для межпроцессного взаимодействияkill()остаётся стандартом. - Альтернативы сигналам: Для сложной межпроцессной коммуникации часто предпочтительнее использовать именованные каналы (FIFO), сокеты домена Unix (Unix domain sockets) или очереди сообщений POSIX, так как они более структурированы и надёжны.