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

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

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

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

}

Рис. 8. Взаимодействие через обмен сигналами.



2003-12-09