Сигналы позволяют осуществить самый примитивный способ коммуникации между двумя процессами. С помощью функции kill() процесс может послать сигнал другому процессу. Затем процесс может реагировать на принятый сигнал. Разумеется, в качестве IPC сигналы используются крайне редко. В качестве примера приведена программа, которая создает с помощью fork() второй процесс. Затем оба процесса (родитель и потомок) обмениваются данными и выводят сообщения на экран. При этом потомок переводится в состояние ожидания, пока родительский процесс выводит сообщение. Родитель посылает сигнал потомку посредством kill(), а затем сам переводится в состояние ожидания. Потомок выводит сообщение, будит родительский процесс и переводится в состояние ожидания и т.д. Программа приведена на рис. 8.
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
enum { FALSE, TRUE };
sigset_t sig_m1, sig_m2, sig_null;
int signal_flag=FALSE;
void sig_func(int signr)
{
start_signalset();
signal_flag = TRUE;
}
void start_signalset()
{
if(signal(SIGUSR1, sig_func) == SIG_ERR)
exit(0);
if(signal(SIGUSR2, sig_func) == SIG_ERR)
exit(0);
sigemptyset(&sig_m1);
sigemptyset(&sig_null);
sigaddset(&sig_m1,SIGUSR1);
sigaddset(&sig_m1,SIGUSR2);
if(sigprocmask(SIG_BLOCK, &sig_m1, &sig_m2) < 0)
exit(0);
}
void message_for_parents(pid_t pid)
{
kill(pid,SIGUSR2);
}
void wait_for_parents()
{
while(signal_flag == FALSE)
sigsuspend(&sig_null);
signal_flag = FALSE;
if(sigprocmask(SIG_SETMASK, &sig_m2, NULL) < 0)
exit(0);
}
void message_for_child(pid_t pid)
{
kill(pid, SIGUSR1);
}
void wait_for_child(void)
{
while(signal_flag == FALSE)
sigsuspend(&sig_null);
signal_flag = FALSE;
if(sigprocmask(SIG_SETMASK, &sig_m2, NULL) < 0)
exit(0);
}
int main()
{
pid_t pid;
char x,y;
start_signalset();
switch( pid = fork())
{
case -1 : fprintf(stderr, "Ошибка fork()\n");
exit(0);
case 0 : /*...в потомке...*/
for(x=2;x<=10;x+=2)
{
wait_for_parents();
write(STDOUT_FILENO, "ping-",strlen("ping-"));
message_for_parents(getppid());
}
exit(0);
default : /*...в родителе....*/
for(y=1;y<=9;y+=2)
{
write(STDOUT_FILENO, "pong-", strlen("pong-"));
message_for_child(pid);
wait_for_child();
}
}
printf("\n\n");
return 0;
}