next up previous contents
Next: Трубы (pipes) Up: Сигналы Previous: Работа с сигналами в   Contents

Применение сигналов для IPC

Сигналы позволяют осуществить самый примитивный способ коммуникации между двумя процессами. С помощью функции kill() процесс может послать сигнал другому процессу, а затем процесс-приемник может реагировать на принятый сигнал. Разумеется, в качестве IPC сигналы используются крайне редко. Для примера приведена программа, которая создает с помощью fork() второй процесс. Затем оба процесса (родитель и потомок) обмениваются данными и выводят сообщения на экран. При этом потомок переводится в состояние ожидания, пока родительский процесс выводит сообщение. Родитель посылает сигнал потомку посредством kill(), а затем сам переводится в состояние ожидания. Потомок выводит сообщение, пробуждает родительский процесс и переводится в состояние ожидания и все повторяется. Программа приведена ниже:

#include <unistd.h>

#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; }



2004-06-22