Главная страница Взаимодействие нетривиальных процессов 35 KilKchildpid. SIGTERM); 36 exitCO): 37 } Функция doit 2-9 Эта функция запускается родительским процессом. Мы измеряем время ее работы. Она помещает 1 байт в канал, из которого читает дочерний процесс, и считывает 1 байт из другого канала, в который сообщение помещается дочерним процессом. При этом измеряется именно то, что мы назвали задержкой, - время передачи небольшого сообщения туда и обратно. Создание каналов 19-20 Создаются два канала, после чего вызов fork порождает дочерний процесс. При этом образуется схема, изображенная на рис. 4.6 (но без закрытия неиспользуемых дескрипторов каналов). Для этого теста требуются два канала, поскольку каналы являются односторонними, а мы хотим передавать сообщение в обе стороны. Дочерний процесс отсылает обратно сообщение 22-27 Дочерний процесс представляет собой бесконечный цикл, в котором однобайтовое сообщение считывается и отсылается обратно. Измерение времени работы родительского процесса 29-34 Родительский процесс вызывает функцию doit для отправки однобайтового сообщения дочернему процессу и получения ответа. После этого мы имеем гарантию, что оба процесса выполняются. Затем функция doit вызывается в цикле с измерением времени задержки. На компьютере Sparc под управлением Solaris 2.6 при запуске программы пять раз подряд мы получим вот что: Solaris % lat pipe 10000 latency: 278.633 usee Solaris % lat pipe 10000 latency: 397.810 usee Solaris % lat pipe 10000 latency: 392.567 usee Solaris % lat pipe 10000 latency: 266.572 usee Solaris % lat pipe 10000 latency: 284.559 usee Среднее для пяти попыток составляет 324 микросекунды, и именно это значение приведено в табл. А.1. Это время учитывает два переключения контекста (от родительского процесса к дочернему и обратно), четыре системных вызова (wri te, read, write, read) и затраты на передачу 1 байта данных по каналу. Программа измерения задержки очередей сообщений Posix Программа измерения задержки для очередей сообщений Posix приведена в листинге А. 15. Листинг А.15. Программа измерения задержки для очереди сообщений Posix bench/lat pxmsg.c 1 #include unpipc.h 2 #define NAMEl lat pxmsgr 3 #define NAME2 lat pxmsg2 4 #define MAXMSG 4 /* место для 4096 байт в очереди */ 5 #define MSGSIZE 1024 6 void 7 doit(mqd t mqsend. mqd t mqrecv) 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 mainCint argc, char **argv) 16 { 17 int i, nloop: 18 mqd t mql, 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[l]): 25 attr.mq maxmsg = MAXMSG: 26 attr.mq msgs i ze = MSGSIZ E: 27 mql = Mq open(Px ipc name(NAMEl), 0 RDWR 0 CREAT, FILE MODE, Sattr): 28 mq2 = Mq open(Px ipc name(NAME2), 0 RDWR 0 CREAT, FILE MODE, Sattr): 29 if ( (childpid =- ForkO) == 0) { 30 for ( : : ) { /* дочерний процесс */ 31 if (Mq receive(mql, buff, MSGSIZE, NULL) != 1) 32 err quit( mq receive error ): 33 Mq send(mq2, buff, 1, 0): 34 } 35 exit(O): 36 } 37 /* родительский процесс */ 38 doitCmql, mq2): 39 Start time(): 40 for (i = 0; i < nloop: i++) 41 doitCmql, mq2); 42 printf( latency: %.3f usec\n , Stop time() / nloop): 43 KilKchildpid, SIGTERM): 44 Mq close(mql); 45 Mq close(mq2): 46 Mq unl ink (Px ipc name( NAMED): 47 Mq unlink(PxJpc name(NAME2)): 48 exit(O); 49 } 25-28 Создаются две очереди сообщений, каждая из которых используется для передачи данных в одну сторону. Хотя для очередей Posix можно указывать приоритет сообщений, функция mq receive всегда возвращает сообщение с наивысшим приоритетом, поэтому мы не можем использовать лишь одну очередь для данного приложения. Измерение задержки очередей сообщений System V в листинге А. 16 приведен текст программы измерения времени задержки для очередей сообщений 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 doitCint msgid) 1 { 8 MsgsndCmsgid, &p2child. 0. 0): 9 if (Msgrcv(msgid. Sinbuf. sizeof(inbuf.mtext). 2. 0) != 0) 10 err quit( msgrcv error ): 11 } 12 int 13 mainCint argc. char **argv) 14 { 15 int i, nloop. msgid: 16 pid t childpid: 17 if (argc != 2) 18 err quit( usage; lat svmsg <#loops> ): 19 nloop = atoi(argv[l]); 20 msgid = Msgget(IPC PRIVATE. IPC CREAT SVMSG MODE); 21 if ( (childpid = ForkO) == 0) { 22 for ( ; ; ) { /* дочерний процесс */ 23 if (Msgrcv(msgid. Sinbuf. sizeof(inbuf.mtext). 1. 0) != 0) 24 err quit( msgrcv error ); 25 Msgsnd(msgid, &child2p. 0. 0); 26 } 27 exit(O): 28 } 29 /* родительский процесс */ 30 doit(msgid); продолжение
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |