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

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

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

Π‘ΠΈΠ³Π½Π°Π»Ρ‹ Posix: Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ‚ΠΈΠΏΠ° Async-Signal-Safe

НСдостаток ΠΏpoΠ³Ρ€aΠΌΠΌΡ‹ ΠΈΠ· листинга 5.8 Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ mq_notify, mq_receive ΠΈ printf ΠΈΠ· ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сигнала. Ни ΠΎΠ΄Π½Ρƒ ΠΈΠ· этих Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΡ‚Ρ‚ΡƒΠ΄Π° Π½Π΅ слСдуСт.

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹Π·Π²Π°Π½Ρ‹ ΠΈΠ· ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сигнала, относятся ΠΊ Π³Ρ€ΡƒΠΏΠΏΠ΅, Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠΉ, согласно Posix, async-signal-safe functions (Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‰ΠΈΠ΅ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡƒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ асинхронных сигналов). Π’ Ρ‚Π°Π±Π». 5.1 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Ρ‹ эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠΎ стандарту Posix вмСстС с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ, появившимися Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Unix 98.

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅Ρ‚ Π² этом спискС, Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒΡΡ ΠΈΠ· ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сигнала. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π² спискС ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ стандартныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_XXX для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ. Из всСх Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ IPC, рассматриваСмых Π² этой ΠΊΠ½ΠΈΠ³Π΅, Π² список ΠΏΠΎΠΏΠ°Π»ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ sem_post, read ΠΈ write (подразумСваСтся, Ρ‡Ρ‚ΠΎ послСдниС Π΄Π²Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ с ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΌΠΈ ΠΊΠ°Π½Π°Π»Π°ΠΌΠΈ ΠΈ FIFO).

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

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ ANSI Π‘ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹Π·Π²Π°Π½Ρ‹ ΠΈΠ· ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сигналов: abort, exit, longjmp, signal. ΠŸΠ΅Ρ€Π²Ρ‹Π΅ Ρ‚Ρ€ΠΈ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ Π² спискС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ async-signal-safe стандарта Unix 98. 


Π’Π°Π±Π»ΠΈΡ†Π° 5.1. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ, относящиСся ΠΊ Π³Ρ€ΡƒΠΏΠΏΠ΅ async-signal-safe

access        fpathconf rename      sysconf

aio_return    fstat     rmdir       tcdrain

aio_suspend   fsync     sem_post    tcflow 

alarm         getegid   setgid      tcflush

cfgetispeed   geteuid   setpgid     tcgetattr

cfgetospeed   getgid    setsid      tcgetgrp

cfsetispeed   getgroups setuid      tcsendbreak

cfsetospeed   getpgrp   sigaction   tcsetattr

chdir         getpid    sigaddset   tcsetpgrp

chmod         getppid   sigdelset   time

chown         getuid    sigemptyset timer_getoverrun

clock_gettime kill      sigfillset  timer_gettime

close         link      sigismember timer_settime

creat         lseek     signal      times

dup           mkdir     sigpause    umask

dup2          mkfifo    sigpending  uname

execle        open      sigprocmask unlink

execve        pathconf  sigqueue    utime

_exit         pause     sigset      wait

fcntl         pipe      sigsuspend  waitpid

fdatasync     raise     sleep       write

fork          read      stat

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ сигналом

Одним ΠΈΠ· способов ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Π²Ρ‹Π·ΠΎΠ²Π° ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΈΠ· ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сигнала являСтся установка этим ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠΌ глобального Ρ„Π»Π°Π³Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ провСряСтся ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ для получСния ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ ΠΏΡ€ΠΈΡ…ΠΎΠ΄Π΅ сообщСния. Π’ листингС 5.9 ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ этот ΠΌΠ΅Ρ‚ΠΎΠ΄, хотя новая ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Ρ‚Π°ΠΊΠΆΠ΅ содСрТит ΠΎΡˆΠΈΠ±ΠΊΡƒ, Π½ΠΎ ΡƒΠΆΠ΅ Π΄Ρ€ΡƒΠ³ΡƒΡŽ, ΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΌΡ‹ вскорС ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅.

Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Π°Ρ пСрСмСнная

2 ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ СдинствСнноС дСйствиС, выполняСмоС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠΌ сигнала, Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² присваивании Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠ³ΠΎ значСния Ρ„Π»Π°Π³Ρƒ mqflag, Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ ΠΈΠ· листинга 5.8 ΡƒΠΆΠ΅ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΡΠ²Π»ΡΡ‚ΡŒΡΡ Ρ‚Π°ΠΊΠΎΠ²Ρ‹ΠΌΠΈ. УмСньшСниС количСства Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… β€” это всСгда Π±Π»Π°Π³ΠΎ, особСнно ΠΏΡ€ΠΈ использовании ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ².

ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ сообщСний

15-18 ΠœΡ‹ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ сообщСний, ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π΅Π΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΈ выдСляСм Π±ΡƒΡ„Π΅Ρ€ считывания.

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

19-22 ΠœΡ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Ρ‚Ρ€ΠΈ Π½Π°Π±ΠΎΡ€Π° сигналов ΠΈ устанавливаСм Π±ΠΈΡ‚ для сигнала SIGUSR1 Π² Π½Π°Π±ΠΎΡ€Π΅ newmask.

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

23-27 ΠœΡ‹ устанавливаСм ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сигнала для SIGUSR1, присваиваСм значСния полям структуры sigevent ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ mq_notify. 

Листинг 5.9. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сигнала устанавливаСт Ρ„Π»Π°Π³ для Π³Π»Π°Π²Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° (Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Π°Ρ вСрсия)

//pxmsg/mqnotifysig2.c

1  #include "unpipc.h"

2  volatile sig_atomic_t mqflag; /* Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ устанавливаСтся ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠΌ */

3  static void sig_usrl(int);


4  int

5  main(int argc, char **argv)

6  {

7   mqd_t mqd;

8   void *buff;

9   ssize_t n;

10  sigset_t zeromask, newmask, oldmask;

11  struct mq_attr attr;

12  struct sigevent sigev;

13  if (argc != 2)

14   err_quit("usage: mqnotifysig2 <name>");

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

16  mqd = Mq_open(argv[1], O_RDONLY);

17  Mq_getattr(mqd, &attr);

18  buff = Malloc(attr.mq_msgsize);

19  Sigemptyset(&zeromask); /* сигналы Π½Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ΡΡ */

20  Sigemptyset(&newmask);

21  Sigemptyset(&oldmask);

22  Sigaddset(&newmask, SIGUSR1);

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

24  Signal(SIGUSR1, sig_usr1);

25  sigev.sigev_notify = SIGEV_SIGNAL;

26  sigev.sigev_signo = SIGUSR1;

27  Mq_notify(mqd, &sigev);

28  for (;;) {

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

30   while (mqflag == 0)

31    sigsuspend(&zeromask);

32   mqflag = 0; /* сброс Ρ„Π»Π°Π³Π° */

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

34   n = Mq_receive(mqd, buff, attr.mq_msgsize, NULL);

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

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

37  }

38  exit(0);

39 }


40 static void

41 sig_usr1(int signo)

42 {

43  mqflag = 1;

44  return;

45 } 

ОТиданиС установки Ρ„Π»Π°Π³Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠΌ

28-32 ΠœΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ sigprocmask, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ SIGUSR1, сохраняя Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ маску сигналов Π² oldmask. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ Π² Ρ†ΠΈΠΊΠ»Π΅ провСряСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ глобального Ρ„Π»Π°Π³Π° mqflag, оТидая, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сигнала установит Π΅Π³ΠΎ Π² Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Пока Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ этого Ρ„Π»Π°Π³Π° Ρ€Π°Π²Π½ΠΎ Π½ΡƒΠ»ΡŽ, ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ sigsuspend, Ρ‡Ρ‚ΠΎ автоматичСски приостанавливаСт Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΈ устанавливаСт Π΅Π³ΠΎ маску Π² zeromask (сигналы Π½Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ΡΡ). Π Π°Π·Π΄Π΅Π» 10.16 [21] рассказываСт ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sigsuspend Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ. Π’Π°ΠΊΠΆΠ΅ Ρ‚Π°ΠΌ ΠΎΠ±ΡŠΡΡΠ½ΡΡŽΡ‚ΡΡ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ mqflag Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ сигналС SIGUSR1. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π΅ ΠΈΠ· sigsuspend сигнал SIGUSR1 блокируСтся.

ΠŸΠ΅Ρ€Π΅Ρ€Π΅Π³ΠΈΡΡ‚Ρ€Π°Ρ†ΠΈΡ ΠΈ считываниС сообщСния

33-36 Когда Ρ„Π»Π°Π³ mqflag ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΌΡ‹ рСгистрируСмся Π½Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ увСдомлСния Π·Π°Π½ΠΎΠ²ΠΎ ΠΈ считываСм сообщСниС ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌ сигнал SIGUSR1 ΠΈ возвращаСмся ΠΊ Π½Π°Ρ‡Π°Π»Ρƒ Ρ†ΠΈΠΊΠ»Π°.

ΠœΡ‹ ΡƒΠΆΠ΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΈ, Ρ‡Ρ‚ΠΎ Π² этой вСрсии ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ присутствуСт ошибка. ΠŸΠΎΡΠΌΠΎΡ‚Ρ€ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚, Ссли Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΏΠΎΠΏΠ°Π΄ΡƒΡ‚ Π΄Π²Π° сообщСния, ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ считано ΠΏΠ΅Ρ€Π²ΠΎΠ΅ ΠΈΠ· Π½ΠΈΡ…. ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΠΌΠΈΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ это, Π΄ΠΎΠ±Π°Π²ΠΈΠ² sleep ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ mq_notify. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Ρ‚ΡƒΡ‚ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ отсылаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ‚ΠΎΠΌ случаС, ΠΊΠΎΠ³Π΄Π° сообщСниС помСщаСтся Π² ΠΏΡƒΡΡ‚ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ. Если Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‚ Π΄Π²Π° сообщСния, ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ ΠΏΠ΅Ρ€Π²ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ считано, Ρ‚ΠΎ отсылаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅. Π’ΠΎΠ³Π΄Π° ΠΌΡ‹ считываСм ΠΏΠ΅Ρ€Π²ΠΎΠ΅ сообщСниС ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ sigsuspend, оТидая поступлСния Π΅Ρ‰Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ. А Π² это врСмя Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΡƒΠΆΠ΅ имССтся сообщСниС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ, Π½ΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΡ‹ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΏΡ€ΠΎΡ‡Ρ‚Π΅ΠΌ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ сигналом с ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ

Π˜ΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΎΠΏΠΈΡΠ°Π½Π½ΡƒΡŽ Π²Ρ‹ΡˆΠ΅ ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΌΠΎΠΆΠ½ΠΎ, ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΠ² Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ считывания сообщСний. Листинг 5.10 содСрТит ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈΠ· листинга 5.9. Новая ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° считываСт сообщСния Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅.

Листинг 5.10. ИспользованиС увСдомлСния с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ сигнала для считывания сообщСния ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ сообщСний Posix

//pxmsg/mqnotifysig3.с

1  #include "unpipc.h"

2  volatile sig_atomic_t mqflag; /* Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ устанавливаСтся ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠΌ сигнала */

3  static void sig_usr1(int);


4  int

5  main(int argc, char **argv)

6  {

7   mqd_t mqd;

8   void *buff;

9   ssize_t n;

10  sigset_t zeromask, newmask, oldmask;

11  struct mq_attr attr;

12  struct sigevent sigev;

13  if (argc != 2)

14   err_quit("usage: mqnotifysig3 <name>");

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

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

17  Mq_getattr(mqd, &attr);

18  buff = Malloc(attr.mq_msgsize);

19  Sigemptyset(&zeromask); /* сигналы Π½Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ΡΡ */

20  Sigemptyset(&newmask);

21  Sigemptyset(&oldmask);

22  Sigaddset(&newmask, SIGUSR1);

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

24  Signal(SIGUSR1, sig_usr1);

25  sigev.sigev_notify = SIGEV_SIGNAL;

26  sigev.sigev_signo = SIGUSR1;

27  Mq_notify(mqd, &sigev);

28  for (;;) {

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

30   while (mqflag == 0)

31    sigsuspend(&zeromask);

32   mqflag = 0; /* сброс Ρ„Π»Π°Π³Π° */

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)