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

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

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

37   if (errno != EAGAIN)

38    err_sys("mq_receive error");

39   Sigprocmask(SIG_UNBLOCK, &newmask, NULL); /* Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌ SIGUSR1 */

40  }

41  exit(0);

42 }


43 static void

44 sig_usr1(int signo)

45 {

46  mqflag = 1;

47  return;

48 }

ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ сообщСний Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½Π½ΠΎΠΉ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ

15-18 ΠŸΠ΅Ρ€Π²ΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅: ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ сообщСний указываСтся Ρ„Π»Π°Π³ O_NONBLOCK.

Π‘Ρ‡ΠΈΡ‚Ρ‹Π²Π°Π½ΠΈΠ΅ всСх сообщСний ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ

34-38 Π”Ρ€ΡƒΠ³ΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅: mq_receive вызываСтся Π² Ρ†ΠΈΠΊΠ»Π΅, считывая всС сообщСния Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, ΠΏΠΎΠΊΠ° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½Π° ошибка с ΠΊΠΎΠ΄ΠΎΠΌ EAGAIN, ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‰Π°Ρ отсутствиС сообщСний Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ. 

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ с использованиСм sigwait вмСсто ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°

Π₯отя ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΈΠ· ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ²Ρ‹ΡΠΈΡ‚ΡŒ Π΅Π΅ ΡΡ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ sigsuspend для Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π² ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ ΠΏΡ€ΠΈΡ…ΠΎΠ΄Π° сообщСния. ΠŸΡ€ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ΠΈΠΈ сообщСния Π² ΠΏΡƒΡΡ‚ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ вызываСтся сигнал, основной ΠΏΠΎΡ‚ΠΎΠΊ останавливаСтся, запускаСтся ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ устанавливаСт Ρ„Π»Π°Π³ mqflag, Π·Π°Ρ‚Π΅ΠΌ снова запускаСтся Π³Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, ΠΎΠ½ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ mqflag ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ ΠΎΡ‚ нуля, ΠΈ считываСт сообщСниС. Π‘ΠΎΠ»Π΅Π΅ простой ΠΈ эффСктивный ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰Π΅ΠΉ получСния сигнала, Ρ‡Ρ‚ΠΎ Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π²Ρ‹Π·ΠΎΠ²Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для установки Ρ„Π»Π°Π³Π°. Π­Ρ‚Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ прСдоставляСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ sigwait:

#include <signal.h>

int sigwait(const sigset_t *set, int *sig);

/* Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ 0 Π² случаС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ, –1 – Π² случаС ошибки */

ΠŸΠ΅Ρ€Π΅Π΄ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ sigwait ΠΌΡ‹ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ сигналы. Набор Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΡ‹Ρ… сигналов указываСтся Π² качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° set. Ѐункция sigwait блокируСтся, ΠΏΠΎΠΊΠ° Π½Π΅ ΠΏΡ€ΠΈΠ΄Π΅Ρ‚ ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· этих сигналов. Когда ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½, функция Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ Π΅Π³ΠΎ. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ этого сигнала сохраняСтся Π² ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ sig, Π° функция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 0. Π­Ρ‚ΠΎ называСтся синхронным ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ΠΌ асинхронного события: ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ сигнал, Π½ΠΎ Π½Π΅ ΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ асинхронным ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠΌ сигнала.

Π’ листингС 5.11 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π΅ΠΉ mq_notifΡƒ ΠΈ sigwait.

Листинг 5.11. ИспользованиС mq_notify совмСстно с sigwait

//pxmsg/mqnotifysig4.c

1  #include "unpipc.h"


2  int

3  main(int argc, char **argv)

4  {

5   int signo;

6   mqd_t mqd;

7   void *buff;

8   ssize_t n;

9   sigset_t newmask;

10  struct mq_attr attr;

11  struct sigevent sigev;

12  if (argc != 2)

13   err_quit("usage: mqnotifysig4 <name>");

14  /* ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ², Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π±ΡƒΡ„Π΅Ρ€Π° */

15  mqd = Mq_open(argv[1], O_RDONLY | O_NONBLOCK);

16  Mq_getattr(mqd, &attr);

17  buff = Malloc(attr.mq_msgsize);

18  Sigemptyset(&newmask);

19  Sigaddset(&newmask, SIGUSR1);

20  Sigprocmask(SIG_BLOCK, &newmask, NULL); /* Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌ SIGUSR1 */

21  /* установка ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°, Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ увСдомлСния */

22  sigev.sigev_notify = SIGEV_SIGNAL;

23  sigev.sigev_signo = SIGUSR1;

24  Mq_notify(mqd, &sigev);

25  for (;;) {

26   Sigwait(&newmask, &signo);

27   if (signo == SIGUSR1) {

28    Mq_notify(mqd, &sigev); /* пСрСрСгистрируСмся */

29    while ((n = mq_receive(mqd, buff, attr.mq_msgsize, NULL)) >= 0) {

30     printf("read %ld bytes\n", (long) n);

31    }

32    if (errno != EAGAIN)

33     err_sys("mq_receive error");

34   }

35  }

36  exit(0);

37 }

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ Π½Π°Π±ΠΎΡ€Π° сигналов ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° SIGUSR1

18-20 Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ ΠΎΠ΄ΠΈΠ½ Π½Π°Π±ΠΎΡ€ сигналов, содСрТащий Ρ‚ΠΎΠ»ΡŒΠΊΠΎ SIGUSR1, Π° Π·Π°Ρ‚Π΅ΠΌ этот сигнал блокируСтся sigprocmask.

ОТиданиС сигнала

26-34 ΠœΡ‹ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈ ΠΆΠ΄Π΅ΠΌ ΠΏΡ€ΠΈΡ…ΠΎΠ΄Π° сигнала, Π²Ρ‹Π·Π²Π°Π² sigwait. ΠŸΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ сигнала SIGUSR1 ΠΌΡ‹ пСрСрСгистрируСмся Π½Π° ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΈ считываСм всС доступныС сообщСния.

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

Ѐункция sigwait часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹Ρ… процСссах. Π”Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, глядя Π½Π° ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ 0 ΠΈΠ»ΠΈ ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· ошибок Π•Ρ…Ρ…Ρ…, Ρ‡Ρ‚ΠΎ вСсьма ΠΏΠΎΡ…ΠΎΠΆΠ΅ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Pthread. Однако Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΌ процСссС нСльзя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ sigprocmask β€” вмСсто Π½Π΅Π΅ слСдуСт Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ pthread_ sigmask, которая измСняСт маску сигналов Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Π²Ρ‹Π·Π²Π°Π²ΡˆΠ΅Π³ΠΎ Π΅Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°. АргумСнты pthread_sigmask ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‚ с Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ sigprocmask.

Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π΄Π²Π° Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sigwait: sigwaitinfo Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ структуру siginfo_t (которая Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅) ΠΈ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° для использования с Π½Π°Π΄Π΅ΠΆΠ½Ρ‹ΠΌΠΈ сигналами; функция sigtimedwait Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ структуру siginfo_t ΠΈ позволяСт Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΌΡƒ процСссу ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π½Π° ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅.

Π‘ΠΎΠ»ΡŒΡˆΠ°Ρ Ρ‡Π°ΡΡ‚ΡŒ ΠΊΠ½ΠΈΠ³ ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ [3], Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΡŽΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ sigwait для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ всСх сигналов Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΌ процСссС ΠΈ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ асинхронныС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ. 

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ сообщСний Posix ΠΈ функция select

ДСскриптор ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ сообщСний (пСрСмСнная Ρ‚ΠΈΠΏΠ° mqd_t) Π½Π΅ являСтся Β«ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌΒ» дСскриптором ΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ с функциями select ΠΈ poll (Π³Π»Π°Π²Π° 6 [24]). Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ ΠΈΡ… ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ вмСстС с ΠΊΠ°Π½Π°Π»ΠΎΠΌ ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ mq_notify. (Аналогичный ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 6.9 для ΠΎΡ‡Π΅Ρ€Π΅Π΄Π΅ΠΉ System V, Π³Π΄Π΅ создаСтся Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс ΠΈ ΠΊΠ°Π½Π°Π» связи.) ΠŸΡ€Π΅ΠΆΠ΄Π΅ всСго ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ, ΡΠΎΠ³Π»Π°ΡΠ½ΠΎ Ρ‚Π°Π±Π». 5.1, функция write ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ ΠΊ Π³Ρ€ΡƒΠΏΠΏΠ΅ async-signal-safe, поэтому ΠΎΠ½Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒΡΡ ΠΈΠ· ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сигналов. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π² листингС 5.12.

Листинг 5.12. ИспользованиС увСдомлСния с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ сигнала ΠΈ ΠΊΠ°Π½Π°Π»Π°

//pxmsg/mqnotifysig5.c

1  #include "unpipc.h"

2  int pipefd[2];

3  static void sig_usr1(int);


4  int

5  main(int argc, char **argv)

6  {

7   int nfds;

8   char c;

9   fd_set rset;

10  mqd_t mqd;

11  void *buff;

12  ssize_t n;

13  struct mq_attr attr;

14  struct sigevent sigev;

15  if (argc != 2)

16   err_quit("usage: mqnotifysig5 <name>");

17  /* ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ², Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π±ΡƒΡ„Π΅Ρ€Π° */

18  mqd = Mq_open(argv[1], O_RDONLY | O_NONBLOCK);

19  Mq_getattr(mqd, &attr);

20  buff = Malloc(attr.mq_msgsize);

21  Pipe(pipefd);

22  /* установка ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°, Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ увСдомлСния */

23  Signal(SIGUSR1, sig_usr1);

24  sigev.sigev_notify = SIGEV_SIGNAL;

25  sigev.sigev_signo = SIGUSR1;

26  Mq_notify(mqd, &sigev);

27  FD_ZERO(&rset);

28  for (;;) {

29   FD_SET(pipefd[0], &rset);

30   nfds = Select(pipefd[0] + 1, &rset, NULL, NULL, NULL);

31   if (FD_ISSET(pipefd[0], &rset)) {

32    Read(pipefd[0], &c, 1);

33    Mq_notify(mqd, &sigev); /* пСрСрСгистрируСмся */

34    while ((n = mq_receive(mqd, buff, attr.mq_msgsize, NULL)) >= 0) {

35     printf("read %ld bytes\n", (long) n);

36    }

37    if (errno != EAGAIN)

38     err_sys("mq_receive error");

39   }

40  }

41  exit(0);

42 }


43 static void

44 sig_usr1(int signo)

45 {

46  Write(pipefd[1], "", 1); /* ΠΎΠ΄ΠΈΠ½ Π±Π°ΠΉΡ‚ – 0 */

47  return;

48 }

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΊΠ°Π½Π°Π»Π°

21 ΠœΡ‹ создаСм ΠΊΠ°Π½Π°Π», Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сигнала ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Ρ‚ запись, ΠΊΠΎΠ³Π΄Π° Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΎ поступлСнии сообщСния Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ. Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования ΠΊΠ°Π½Π°Π»Π° Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ процСсса.

Π’Ρ‹Π·ΠΎΠ² select

27-40 ΠœΡ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π°Π±ΠΎΡ€ дСскрипторов rset ΠΈ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΏΡ€ΠΎΡ…ΠΎΠ΄Π΅ Ρ†ΠΈΠΊΠ»Π° Π²ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ Π±ΠΈΡ‚, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ дСскриптору pipefd[0] (ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ Π½Π° считываниС ΠΊΠΎΠ½Π΅Ρ† ΠΊΠ°Π½Π°Π»Π°). Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ select, оТидая получСния СдинствСнного дСскриптора, хотя Π² Ρ‚ΠΈΠΏΠΈΡ‡Π½ΠΎΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΈΠΌΠ΅Π½Π½ΠΎ здСсь ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΠ»ΠΎΡΡŒ Π±Ρ‹ Ρ€Π°Π·ΠΌΠ½ΠΎΠΆΠ΅Π½ΠΈΠ΅ дСскрипторов ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· ΠΊΠΎΠ½Ρ†ΠΎΠ² ΠΊΠ°Π½Π°Π»Π°. Когда появляСтся Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΈΠ· ΠΊΠ°Π½Π°Π»Π°, ΠΌΡ‹ пСрСрСгистрируСмся Π½Π° ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΈ считываСм всС доступныС сообщСния.

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сигнала

43-48 ЕдинствСнноС, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сигнала, β€” записываСт Π² ΠΊΠ°Π½Π°Π» 1 Π±Π°ΠΉΡ‚. Как ΠΌΡ‹ ΡƒΠΆΠ΅ ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π»ΠΈ, эта опСрация относится ΠΊ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½Π½Ρ‹ΠΌ для асинхронных ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ².

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: запуск Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°

ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²ΠΎΠΉ ΡΠ½ΡΡ‚ΠΈΡŽ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ сигналом являСтся присваиваниС sigev_notify значСния SIGEV_THREAD, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ созданию Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°. Ѐункция, указанная Π² sigev_notify_function, вызываСтся с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ sigev_value. Атрибуты Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ°Π½Π°Π»Π° ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ sigev_notify_attributes, которая ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈ Π½ΡƒΠ»Π΅Π²Ρ‹ΠΌ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ, Ссли нас ΡƒΡΡ‚Ρ€Π°ΠΈΠ²Π°ΡŽΡ‚ устанавливаСмыС ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹. ВСкст ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π² листингС 5.13.

Листинг 5.13. Ѐункция mq_notify, Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‰Π°Ρ Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ

//pxmsg/mqnotifythread1.с