Π‘ΠΈΠ³Π½Π°Π»Ρ 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)