//svmsg/msgrcv.c
1 #include "unpipc.h"
2 #define MAXMSG (8192 + sizeof(long))
3 int
4 main(int argc, char **argv)
5 {
6 int c, flag, mqid;
7 long type;
8 ssize_t n;
9 struct msgbuf *buff;
10 type = flag = 0;
11 while ((c = Getopt(argc, argv, "nt:")) != –1) {
12 switch (c) {
13 case 'n':
14 flag |= IPC_NOWAIT;
15 break;
16 case 't':
17 type = atol(optarg);
18 break;
19 }
20 }
21 if (optind != argc – 1)
22 err_quit("usage: msgrcv [ –n ] [ –t type ]
23 mqid = Msgget(Ftok(argv[optind], 0), MSG_R);
24 buff = Malloc(MAXMSG);
25 n = Msgrcv(mqid, buff, MAXMSG, type, flag);
26 printf("read %d bytes, type = %ld\n", n, buff->mtype);
27 exit(0);
28 }
Программа msgrmid
Для удаления очереди сообщений мы вызываем функцию msgctl с командой IPC_RMID, как показано в листинге 6.5.
//svmsg/msgrmid.c
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int mqid;
6 if (argc != 2)
7 err_quit("usage: msgrmid
8 mqid = Msgget(Ftok(argv[1], 0), 0);
9 Msgctl(mqid, IPC_RMID, NULL);
10 exit(0);
11 }
Примеры
Теперь воспользуемся четырьмя только что написанными программами. Создадим очередь и поместим в нее три сообщения:
solaris % msgcreate /tmp/no/such/file
ftok error for pathname "tmp/no/such/file" and id 0: No such file or directory
solaris % touch /trap/test1
solaris % msgcreate /tmp/test1
solaris % msgsnd /tmp/test1 1 100
solaris % msgsnd /tmp/test1 2 200
solaris % msgsnd /tmp/test1 3 300
solaris % ipcs –qo
IPC status from
T ID KEY MODE OWNER GROUP CBYTES QNUM
Message Queues:
q 100 0х0000113e –rw-r--r-- rstevens other1 6 3
Сначала мы пытаемся создать очередь, используя имя несуществующего файла. Пример показывает, что файл, указываемый в качестве аргумента ftok, обязательно должен существовать. Затем мы создаем файл /tmp/test1 и используем его имя при создании очереди сообщений. После этого в очередь помещаются три сообщения длиной 1, 2 и 3 байта со значениями типа 100, 200 и 300 (вспомните рис. 6.1). Программа ipcs показывает, что в очереди находятся 3 сообщения общим объемом 6 байт.
Теперь продемонстрируем использование аргумента type при вызове msgrcv для считывания сообщений в произвольном порядке:
solaris % msgrcv –t 200 /tmp/test1
read 2 bytes, type = 200
solaris % msgrcv –t -300 /tmp/test1
read 1 bytes, type = 100
solaris % msgrcv /tmp/test1
read 3 bytes, type = 300
solaris % msgrcv –n /tmp/test1
msgrcv error: No message of desired type
В первом примере запрашивается сообщение с типом 200, во втором примере — сообщение с наименьшим значением типа, не превышающим 300, а в третьем — первое сообщение в очереди. Последний запуск msgrcv иллюстрирует действие флага IPC_NOWAIT.
Что произойдет, если мы укажем положительное значение типа, а сообщений с таким типом в очереди не обнаружится?
solaris % ipcs –qo
IPC status from
T ID KEY MODE OWNER GROUP CBYTES QNUM
Message Queues:
q 100 0x0000113e –rw-r--r-- rstevens other1 0 0
solaris % msgsnd /tmp/test1 1 100
solaris % msgrcv –t 999 /temp/test1