Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX: взаимодСйствиС процСссов». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 39

Автор Уильям БтивСнс

10  for (;;) {

11   /* считываниС ΠΏΠΎΠ»Π½ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ ΠΈΠ· ΠΊΠ°Π½Π°Π»Π° IPC */

12   mesg.mesg_type = 1:

13   if ((n = Mesg_recv(readfd, &mesg)) == 0) {

14    err_msg("pathname missing");

15    continue;

16   }

17   mesg.mesg_data[n] = '\0'; /* ΠΏΠΎΠ»Π½ΠΎΠ΅ имя */

18   if ((ptr = strchr(mesg.mesg_data, ' ')) == NULL) {

19    err_msg("bogus request: %s", mesg.mesg_data);

20    continue;

21   }

22   *ptr++ =0; /* ptr = ΠΏΠΎΠ»Π½ΠΎΠ΅ имя */

23   pid = atol(mesg.mesg_data);

24   mesg.mesg_type = pid; /* для ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹Ρ… сообщСний */

25   if ((fp = fopen(ptr, "r")) == NULL) {

26    /* 4error: must tell client */

27    snprintf(mesg.mesg_data + n, sizeof(mesg.mesg_data) – n,

28     ": can't open. %s\n", strerror(errno));

29    mesg.mesg_len – strlen(ptr);

30    memmove(mesg.mesg_data, ptr, mesg.mesg_len);

31    Mesg_send(writefd, &mesg);

32   } else {

33    /* Ρ„Π°ΠΉΠ» ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚, ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ */

34    while (Fgets(mesg.mesg_data, MAXMESGDATA, fp) != NULL) {

35     mesg.mesg_len = strlen(mesg.mesg_data);

36     Mesg_send(writefd, &mesg);

37    }

38    Fclose(fp);

39   }

40   /* сообщСниС Π½ΡƒΠ»Π΅Π²ΠΎΠΉ Π΄Π»ΠΈΠ½Ρ‹ Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Π΅Ρ‚ связь */

41   mesg.mesg_len = 0;

42   Mesg_send(writefd, &mesg);

43  }

44 }

Листинг 6.14. Ѐункция main ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

//svmsgmpx1q/client_main.c

1  #include "svmsg.h"

2  void client(int, int);


3  int

4  main(int argc, char **argv)

5  {

6   int msqid;

7   /* сСрвСр Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Π» ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ */

8   msqid = Msgget(MQ_KEY1, 0);

9   client(msqid, msqid); /* ΠΎΠ΄Π½Π° ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Π² ΠΎΠ±Π΅ стороны */

10  exit(0);

11 }

Листинг 6.15. Ѐункция client

//svmsgmpx1q/client.с

1  #include "mesg.h"


2  void

3  client(int readfd, int writefd)

4  {

5   size_t len;

6   ssize_t n;

7   char *ptr;

8   struct mymesg mesg;

9   /* ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π±ΡƒΡ„Π΅Ρ€ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠΌ процСсса ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»ΠΎΠΌ */

10  snprintf(mesg.mesg_data, MAXMESGDATA. "%ld ", (long) getpid());

11  len = strlen(mesg.mesg_data);

12  ptr = mesg.mesg_data + len;

13  /* считываСм ΠΏΠΎΠ»Π½ΠΎΠ΅ имя Ρ„Π°ΠΉΠ»Π° */

14  Fgets(ptr, MAXMESGDATA – len, stdin);

15  len = strlen(mesg.mesg_data);

16  if (mesg.mesg_data[len-1] == '\n')

17   len--; /* удаляСм ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ строки fgets() */

18  mesg.mesg_len = len;

19  mesg.mesg_type = 1;

20  /* записываСм PID ΠΈ имя Ρ„Π°ΠΉΠ»Π° Π² ΠΊΠ°Π½Π°Π» IPC */

21  Mesg_send(writefd, &mesg);

22  /* считываСм ΠΈΠ· ΠΊΠ°Π½Π°Π»Π° IPC, записываСм Π² stdout */

23  mesg.mesg_type = getpid();

24  while ((n = Mesg_recv(readfd, &mesg)) > 0)

25   Write(STDOUT_FILENO, mesg.mesg_data, n);

26 } 

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: ΠΎΠ΄Π½Π° ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

ИзмСним Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ всС запросы ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π»ΠΈΡΡŒ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΉ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, Π½ΠΎ для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ² использовалась Π±Ρ‹ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. На рис. 6.3 ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Π° схСма Ρ‚Π°ΠΊΠΎΠ³ΠΎ прилоТСния. 

Рис. 6.3. Одна ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ для сСрвСра ΠΈ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΉ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°


ΠšΠ»ΡŽΡ‡ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ сСрвСра Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ извСстСн ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ, Π° сами ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ свои ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ с ΠΊΠ»ΡŽΡ‡ΠΎΠΌ IPC_PRIVATE. ВмСсто ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ сСрвСру ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° процСсса ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρ‹ ΡΠΎΠΎΠ±Ρ‰Π°ΡŽΡ‚ Π΅ΠΌΡƒ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ своСй ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ сСрвСр направляСт свой ΠΎΡ‚Π²Π΅Ρ‚. Π­Ρ‚ΠΎΡ‚ сСрвСр являСтся ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹ΠΌ: для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° пороТдаСтся ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ процСсс.

ΠŸΠ Π˜ΠœΠ•Π§ΠΠΠ˜Π•

ΠŸΡ€ΠΈ Ρ‚Π°ΠΊΠΎΠΉ схСмС ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² случаС Β«Π³ΠΈΠ±Π΅Π»ΠΈΒ» ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Ρ‚ΠΎΠ³Π΄Π° сообщСния останутся Π² Π΅Π³ΠΎ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ навсСгда (ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ Π΄ΠΎ ΠΏΠ΅Ρ€Π΅Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ядра ΠΈΠ»ΠΈ явного удалСния ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌ процСссом).

ΠΠΈΠΆΠ΅ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ ΠΏΡ€Π΅Ρ‚Π΅Ρ€ΠΏΠ΅Π²Π°ΡŽΡ‚ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΌΠΈ вСрсиями:

β–  mesg.h (листинг 4.12);

β–  svmsg.h (листинг 6.7);

β–  Ρ„ункция main сСрвСра (листинг 6.12);

β–  Ρ„ункция mesg_send (листинг 4.13).

Ѐункция main ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π² листингС 6.16; ΠΎΠ½Π° слСгка измСнилась ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с листингом 6.14. ΠœΡ‹ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ сСрвСра с извСстным ΠΊΠ»ΡŽΡ‡ΠΎΠΌ (MQ_KEY1) ΠΈ создаСм Π½Π°ΡˆΡƒ ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ с ΠΊΠ»ΡŽΡ‡ΠΎΠΌ IPC_PRIVATE. Π”Π²Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° этих ΠΎΡ‡Π΅Ρ€Π΅Π΄Π΅ΠΉ становятся Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ client (листинг 6.17). ПослС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π΅Π³ΠΎ ΠΏΠ΅Ρ€ΡΠΎΠ½Π°Π»ΡŒΠ½Π°Ρ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ удаляСтся.

Листинг 6.16. Ѐункция main ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

//svmsgmpxnq/client_main.с

1  #include "svmsg.h"


2  void client(int, int);

3  int

4  main(int argc, char **argv)

5  {

6   int readid, writeid;

7   /* сСрвСр Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ */

8   writeid = Msgget(MQ_KEY1, 0);

9   /* ΠΌΡ‹ создаСм свою ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ */

10  readid = Msgget(IPC_PRIVATE, SVMSG_MODE | IPC_CREAT);

11  client(readid, writeid);

12  /* ΠΈ удаляСм Π½Π°ΡˆΡƒ ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ */

13  Msgctl(readid, IPC_RMID, NULL);

14  exit(0);

15 }

Листинг 6.17. Ѐункция client

//svmsgmpxnq/client.с

1  #include "mesg.h"


2  void

3  client(int readid, int writeid)

4  {

5   size_t len;

6   ssize_t n;

7   char *ptr;

8   struct mymesg mesg;

9   /* ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π±ΡƒΡ„Π΅Ρ€ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠΌ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»ΠΎΠΌ */

10  snprintf(mesg.mesg_data, MAXMESGDATA, "%d ", readid);

11  len = strlen(mesg.mesg_data);

12  ptr = mesg.mesg_data + len;

13  /* считываСм имя Ρ„Π°ΠΉΠ»Π° */

14  Fgets(ptr, MAXMESGDATA – len, stdin);

15  len = strlen(mesg.mesg_data);

16  if (mesg.mesg_data[len-1] == '\n')

17   len--; /* удаляСм ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ строки fgets() */

18  mesg.mesg_len = len;

19  mesg.mesg_type = 1;

20  /* отправляСм ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΠΈ имя Ρ„Π°ΠΉΠ»Π° сСрвСру */

21  Mesg_send(writeid, &mesg);

22  /* считываСм ΠΎΡ‚Π²Π΅Ρ‚ ΠΈΠ· нашСй ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΠΈ записываСм Π΅Π³ΠΎ Π² stdout */

23  while ((n = Mesg_recv(readid, &mesg)) > 0)

24   Write(STDOUT_FILENO, mesg.mesg_data, n);

25 }

Π’ листингС 6.17 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ client. Π­Ρ‚Π° функция практичСски ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ· листинга 6.15, Π½ΠΎ вмСсто ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° процСсса ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π½Π° сСрвСр направляСтся ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Π’ΠΈΠΏ сообщСния Π² структурС mesg остаСтся Ρ€Π°Π²Π½Ρ‹ΠΌ 1, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ устанавливаСтся для сообщСний, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… Π² ΠΎΠ±Π΅ стороны.

Π’ листингС 6.19 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° функция server. Π“Π»Π°Π²Π½ΠΎΠ΅ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ листинга 6.13 Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ эта функция прСдставляСт собой бСсконСчный Ρ†ΠΈΠΊΠ», Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° вызываСтся fork.

Установка ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сигнала для SIGCHLD

10 ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° пороТдаСтся ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ процСсс, Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠ·Π°Π±ΠΎΡ‚ΠΈΡ‚ΡŒΡΡ ΠΎ процСссах-Π·ΠΎΠΌΠ±ΠΈ. Π’ Ρ€Π°Π·Π΄Π΅Π»Π°Ρ… 5.9 ΠΈ 5.10 [24] ΠΎΠ± этом говорится ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ. Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ просто установим ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ для сигнала SIGCHLD, ΠΈ наша функция sig_chld (листинг 6.18) Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒΡΡ ΠΏΡ€ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅Π³ΠΎ процСсса.

12-18 ΠŸΠΎΡ€ΠΎΠ΄ΠΈΠ²ΡˆΠΈΠΉ процСсс сСрвСра блокируСтся Π² Π²Ρ‹Π·ΠΎΠ²Π΅ mesg_recv, оТидая появлСния сообщСния ΠΎΡ‚ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°.

25-45 Π’Ρ‹Π·ΠΎΠ²ΠΎΠΌ fork пороТдаСтся Π½ΠΎΠ²Ρ‹ΠΉ процСсс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΡƒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ Π·Π°ΠΏΡ€ΠΎΡˆΠ΅Π½Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» ΠΈ отправляСт ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ Π»ΠΈΠ±ΠΎ сообщСниС ΠΎΠ± ошибкС, Π»ΠΈΠ±ΠΎ содСрТимоС Ρ„Π°ΠΉΠ»Π°. ΠœΡ‹ ΠΏΡ€Π΅Π΄Π½Π°ΠΌΠ΅Ρ€Π΅Π½Π½ΠΎ помСстили Π²Ρ‹Π·ΠΎΠ² fopen Π² Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс, Π° Π½Π΅ Π² Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ссли Ρ„Π°ΠΉΠ» находится Π² ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΉ Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС, Π΅Π³ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π½ΡΡ‚ΡŒ довольно ΠΌΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π² случаС наличия ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ с ΡΠ΅Ρ‚ΡŒΡŽ.

Ѐункция-ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ для SIGCHLD ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π² листингС 6.18. Она скопирована с листинга 5.11 [24].

Листинг 6.18. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сигнала SIGCHLD, Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ waitpid

//svmsgmpxnq/sigchldwaitpid.с

1 #include "unpipc.h"


2 void

3 sig_chld(int signo)

4 {

5  pid_t pid;

6  int stat;

7  while ((pid = waitpid(-1, &stat, WNOHANG)) > 0);

8  return;

9 }

ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° происходит цикличСский Π²Ρ‹Π·ΠΎΠ² waitpid для получСния статуса Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ всСх Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… процСссов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³Π»ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ. Π—Π°Ρ‚Π΅ΠΌ происходит Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ ΠΈΠ· ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сигнала. ΠŸΡ€ΠΈ этом ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π² Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ состоянии (ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ mesg_recv, листинг 6.9). ΠŸΡ€ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΈΠ· ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° этот Π²Ρ‹Π·ΠΎΠ² msgrcv прСрываСтся. Ѐункция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ с ΠΊΠΎΠ΄ΠΎΠΌ EINTR, ΠΊΠ°ΠΊ рассказываСтся Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 5.9 [24]. 

Нам Π½ΡƒΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠΉ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ ΠΈΠ· Π²Ρ‹Π·Π²Π°Π½Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, поэтому ΠΌΡ‹ пишСм Π½ΠΎΠ²ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-ΠΎΠ±Π΅Ρ€Ρ‚ΠΊΡƒ Mesg_recv, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΡƒΡŽ Π² листингС 6.20. Π­Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° допускаСт Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ошибки с ΠΊΠΎΠ΄ΠΎΠΌ EINTR Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ mesg_recv (которая просто Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ msgrcv), ΠΈ, Ссли это происходит, ΠΌΡ‹ просто Π΅Ρ‰Π΅ Ρ€Π°Π· Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ mesg_recv.

Листинг 6.19. Ѐункция server

//svmsgmpxnq/server.c