На некоторых постерах уже упоминались трубы и kqueue
. Фактически вы также можете создать пару подключенных доменных сокетов Unix с помощью вызова socketpair()
. Тип сокета должен быть SOCK_STREAM
.
Предположим, у вас есть два дескриптора файлов сокетов: fd1, fd2. Теперь fork()
для создания дочернего процесса, который будет наследовать fds. В родительском вы закрываете fd2, а в дочернем вы закрываете fd1. Теперь каждый процесс может poll()
оставшийся открытый файл на своем конце для события POLLIN
. Пока каждая сторона явно не указывает close()
свой fd в течение обычного времени жизни, вы можете быть совершенно уверены, что флаг POLLHUP
должен указывать окончание другой стороны (независимо от того, чиста она или нет). После уведомления об этом событии ребенок может решить, что ему делать (например, умереть).
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <poll.h>
#include <stdio.h>
int main(int argc, char ** argv)
{
int sv[2]; /* sv[0] for parent, sv[1] for child */
socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
pid_t pid = fork();
if ( pid > 0 ) { /* parent */
close(sv[1]);
fprintf(stderr, "parent: pid = %d\n", getpid());
sleep(100);
exit(0);
} else { /* child */
close(sv[0]);
fprintf(stderr, "child: pid = %d\n", getpid());
struct pollfd mon;
mon.fd = sv[1];
mon.events = POLLIN;
poll(&mon, 1, -1);
if ( mon.revents & POLLHUP )
fprintf(stderr, "child: parent hung up\n");
exit(0);
}
}
Вы можете попробовать скомпилировать приведенный выше код проверки концепции и запустить его в терминале, например ./a.out &
. У вас есть примерно 100 секунд, чтобы поэкспериментировать с уничтожением родительского PID различными сигналами, иначе он просто выйдет. В любом случае, вы должны увидеть сообщение «child: parent Hangable».
По сравнению с методом, использующим обработчик SIGPIPE
, этот метод не требует попытки вызова write()
.
Этот метод также симметричен , т.е. процессы могут использовать один и тот же канал для мониторинга существования друг друга.
Это решение вызывает только функции POSIX. Я пробовал это в Linux и FreeBSD. Я думаю, что это должно работать на других Unix, но я действительно не проверял.
Смотри также:
unix(7)
справочных страниц Linux, unix(4)
для FreeBSD, poll(2)
, socketpair(2)
, socket(7)
для Linux.