🐧 Управление процессами через pidfd без опасных гонок с PID
👁 PID в Linux — не уникальный идентификатор на всё время жизни процесса. После завершения процесса его номер может быстро достаться другому. Поэтому автоматизация, которая хранит PID и позже отправляет ему сигнал, потенциально может обратиться уже не к тому процессу. pidfd решает эту проблему: ядро выдаёт файловый дескриптор, привязанный именно к конкретному процессу.
📝 Получение pidfd и безопасная отправка сигнала
Вместо обычного kill(pid, SIGTERM) сигнал отправляется через дескриптор конкретного процесса. Даже если исходный PID уже был переиспользован, pidfd не переключится на новый процесс.
#define _GNU_SOURCE
#include <sys/syscall.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
int main(void)
{
pid_t pid = 12345;
int pidfd = syscall(SYS_pidfd_open, pid, 0);
if (pidfd == -1) {
perror("pidfd_open");
return 1;
}
if (syscall(SYS_pidfd_send_signal,
pidfd, SIGTERM, NULL, 0) == -1) {
perror("pidfd_send_signal");
return 1;
}
close(pidfd);
}
📝 Ожидание завершения процесса через poll
pidfd можно использовать как обычный файловый дескриптор: ждать завершения процесса через poll или epoll, объединяя управление процессами с обычным событийным циклом.
#include <poll.h>
#include <stdio.h>
#include <unistd.h>
int wait_process(int pidfd)
{
struct pollfd pfd = {
.fd = pidfd,
.events = POLLIN
};
int rc = poll(&pfd, 1, 10000);
if (rc == 0) {
printf("timeout\n");
return 1;
}
if (pfd.revents & POLLIN)
printf("process exited\n");
return 0;
}
📝 Получение pidfd напрямую при создании процесса
В реальных системах удобнее использовать clone3() с CLONE_PIDFD: ядро сразу возвращает pidfd для нового процесса. Это особенно интересно для собственных рантаймов, менеджеров процессов и систем автоматизации, где жизненный цикл дочерних процессов контролируется программно.
#define _GNU_SOURCE
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
int pidfd;
pid_t pid = clone(
NULL, NULL, 0, NULL
);
printf("pid=%d\n", pid);
return 0;
}
❗️ pidfd — современный механизм Linux, который устраняет целый класс ошибок, связанных с переиспользованием PID. Для разработчиков системных сервисов это особенно полезно при создании воркеров, супервизоров и собственных менеджеров процессов, где надёжное управление жизненным циклом важнее привычного kill().
tags: #linux #разработка #полезно
🧭 @recura_tech 🌐 VK 🌐 MAX