latency: 392.567 usec
solaris % lat_pipe 10000
latency: 266.572 usec
solaris % lat_pipe 10000
latency: 284.559 usec
Среднее для пяти попыток составляет 324 микросекунды, и именно это значение приведено в табл. А.1. Это время учитывает два переключения контекста (от родительского процесса к дочернему и обратно), четыре системных вызова (write, read, write, read) и затраты на передачу 1 байта данных по каналу.
Программа измерения задержки очередей сообщений Posix
Пpoгрaммa измерения задержки для очередей сообщений Posix приведена в листинге А.15.
//bench/lat_pxmsg.с
1 #include "unpipc.h"
2 #define NAME1 "lat_pxmsg1"
3 #define NAME2 "lat_pxmsg2"
4 #define MAXMSG 4 /* место для 4096 байт в очереди */
5 #define MSGSIZE 1024
6 void
7 doit(mqd_t mqsend, mqd_t mqrecv)
8 {
9 char buff[MSGSIZE];
10 Mq_send(mqsend, buff, 1.0);
11 if (Mq_receive(mqrecv, buff, MSGSIZE, NULL) != 1)
12 err_quit("mq_receive error");
13 }
14 int
15 main(int argc, char **argv)
16 {
17 int i, nloop;
18 mqd_t mq1, mq2;
19 char buff[MSGSIZE];
20 pid_t childpid;
21 struct mq_attr attr;
22 if (argc != 2)
23 err_quit("usage: lat_pxmsg <#loops>");
24 nloop = atoi(argv[1]);
25 attr.mq_maxmsg = MAXMSG;
26 attr.mq_msgsize = MSGSIZE;
27 mq1 = Mq_open(Px_ipc_name(NAME1), O_RDWR | O_CREAT, FILE_MODE, &attr);
28 mq2 = Mq_open(Px_ipc_name(NAME2), O_RDWR | O_CREAT, FILE_MODE, &attr);
29 if ((childpid = Fork()) == 0) {
30 for(;;) { /* дочерний процесс */
31 if (Mq_receive(mq1, buff, MSGSIZE, NULL) != 1)
32 err_quit("mq_receive error");
33 Mq_send(mq2, buff, 1.0);
34 }
35 exit(0);
36 }
37 /* родительский процесс */
38 doit(mq1, mq2);
39 Start_time();
40 for (i = 0; i < nloop; i++)
41 doit(mq1, mq2);
42 printf("latency: %.3f usec\n", Stop_time() / nloop);
43 Kill(childpid, SIGTERM);
44 Mq_close(mq1);
45 Mq_close(mq2);
46 Mq_unlink(Px_ipc_name(NAMED);
47 Mq_unlink(Px_ipc_name (NAME2));
48 exit(0);
49 }
25-28 Создаются две очереди сообщений, каждая из которых используется для передачи данных в одну сторону. Хотя для очередей Posix можно указывать приоритет сообщений, функция mq_receive всегда возвращает сообщение с наивысшим приоритетом, поэтому мы не можем использовать лишь одну очередь для данного приложения.
Измерение задержки очередей сообщений System V
В листинге А.16 приведен текст программы измерения времени задержки для очередей сообщений System V.
//bench/lat_svmsg.c
1 #include "unpipc.h"
2 struct msgbuf p2child = { 1, { 0 } }; /* type = 1 */
3 struct msgbuf child2p = { 2, { 0 } }; /* type = 2 */
4 struct msgbuf inbuf;
5 void
6 doit(int msgid)
7 {
8 Msgsnd(msgid, &p2child, 0, 0);
9 if (Msgrcv(msgid, &inbuf, sizeof(inbuf.mtext), 2, 0) != 0)
10 err_quit("msgrcv error");
11 }
12 int
13 main(int argc, char **argv)
14 {
15 int i, nloop, msgid;
16 pid_t childpid;
17 if (argc != 2)
18 err_quit("usage: lat_svmsg <#loops>");