Ответ
В 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, так как они более структурированы и надёжны.
Ответ 18+ 🔞
Э, слушай, вот сидишь ты, пишешь свой код, и вдруг — бац! — нужно какому-то процессу намекнуть, что пора бы и честь знать. Ну или просто проверить, жив ли он ещё. В Linux для этого есть старый добрый системный вызов kill(). Да-да, название обманчивое, он не только убивать умеет, он вообще сигналы слать может, любые. Ёпта, назвали бы send_signal() и не было бы путаницы.
Вот смотри, как это работает, на пальцах. Берёшь и пишешь:
#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;
}
Теперь по пунктам, а то подозрение ебать чувствую, что не всё понятно.
Во-первых, права. Не любой процесс может любому другому сигнал послать. Ты либо должен быть его владельцем, либо королём системы — рутом. Иначе получишь отлуп, и правильно. Доверия ебать ноль в современных системах к таким вещам.
Во-вторых, есть два священных монстра: SIGKILL (это девятка) и SIGSTOP. Это как мама, которая говорит «всё, хватит». Процесс не может их перехватить, проигнорировать или заблокировать. Это хуй с горы, который всех рассудит. Хочешь гарантированно прибить зависший процесс — шли девятку.
В-третьих, если у тебя программа многопоточная, тут начинается ёперный театр. Функция kill() шлёт сигнал всему процессу целиком. А если тебе нужно ткнуть пальцем в конкретный поток, то это уже pthread_kill(). Не перепутай, а то будет тебе хиросима и нигерсраки в рантайме.
Ещё есть в C++11 свой интерфейс, std::signal, но он больше для внутренней кухни, когда ты сам себе сигналы ловишь. А чтобы соседу по памяти настучать, kill() — это классика, манда с ушами, но работает.
И главное, чувак, запомни: сигналы — это как кричать через стену. Быстро, дёшево, но понять, что именно тебе кричат, сложно. Для нормального, вменяемого общения между процессами есть инструменты понадёжнее: именованные каналы, юникс-сокеты, очереди сообщений. Это уже как полноценный разговор, а не пинок под зад. Но если нужно просто и быстро — kill() твой друг. Только аккуратно, ходишь по охуенно тонкому льду с этими правами и номерами сигналов.