Читать «UNIX: взаимодействие процессов» онлайн - страница 312
Уильям Ричард Стивенс
8 } = 1;
9 } = 0x31230001;
Листинг A.12. Клиент RPC для измерения полосы пропускания
//bench/bw_sunrpc_client.с
1 #include "unpipc.h"
2 #include "bw_sunrpc.h"
3 void *buf;
4 int totalnbytes, xfersize;
5 int
6 main(int argc, char **argv)
7 {
8 int i, nloop, ntowrite;
9 CLIENT *cl;
10 data_in in;
11 if (argc != 6)
12 err_quit("usage: bw_sunrpc_client <hostname> <#loops>"
13 " <#mbytes> <#bytes/write> <protocol>");
14 nloop = atoi(argv[2]);
15 totalnbytes = atoi(argv[3]) * 1024 * 1024;
16 xfersize = atoi(argv[4]);
17 buf = Valloc(xfersize);
18 Touch(buf, xfersize);
19 cl = Clnt_create(argv[1], BW_SUNRPC_PROG, BW_SUNRPC_VERS, argv[5]);
20 Start_time();
21 for (i = 0; i < nloop; i++) {
22 ntowrite = totalnbytes;
23 while (ntowrite > 0) {
24 in.data.data_len = xfersize;
25 in.data.data_val = buf;
26 if (bw_sunrpc_1(&in, cl) == NULL)
27 err_quit("%s", clnt_sperror(cl, argv[1]));
28 ntowrite –= xfersize;
29 }
30 }
31 printf("bandwidth: %.3f MB/sec\n",
32 totalnbytes / Stop_time() * nloop);
33 exit(0);
34 }
Листинг A.13. Процедура сервера для измерения полосы пропускания RPC
//bench/bw_sunrpc_server.c
1 #include "unpipc.h"
2 #include "bw_sunrpc.h"
3 #ifndef RPCGEN_ANSIC
4 #define bw_sunrpc_1_svc bw_sunrpc_1
5 #endif
6 void *
7 bw_sunrpc_1_svc(data_in *inp, struct svc_req *rqstp)
8 {
9 static int nbytes;
10 nbytes = inp->data.data_len;
11 return(&nbytes); /* должен быть ненулевым, но xdr_void игнорирует */
12 }
А.4. Измерение задержки передачи сообщений: программы
Приведем текст трех программ, измеряющих задержку при передаче сообщений по каналам, очередям Posix и очередям System V. Данные о производительности, полученные с их помощью, приведены в табл. А.1.
Программа измерения задержки канала
Программа для измерения задержки канала приведена в листинге А.14.
Листинг А.14. Программа измерения задержки канала
//bench/lat_pipe.c
1 #include "unpipc.h"
2 void
3 doit(int readfd, int writefd)
4 {
5 char c;
6 Write(writefd, &c, 1);
7 if (Read(readfd, &c, 1) != 1)
8 err_quit("read error");
9 }
10 int
11 main(int argc, char **argv)
12 {
13 int i, nloop, pipe1[2], pipe2[2];
14 char c;
15 pid_t childpid;
16 if (argc != 2)
17 err_quit("usage: lat_pipe <#loops>");
18 nloop = atoi(argv[1]);
19 Pipe(pipe1);
20 Pipe(pipe2);
21 if ((childpid = Fork()) == 0) {
22 for(;;) { /* дочерний процесс */
23 if (Read(pipe1[0], &c, 1) != 1)
24 err_quit("read error");
25 Write(pipe2[1], &c, 1);
26 }
27 ехit(0);
28 }
29 /* родительский процесс */
30 doit(pipe2[0], pipe1[1]);
31 Start_time();
32 for (i = 0; i < nloop; i++)
33 doit(pipe2[0], pipe1[1]);
34 printf("latency: %.3f usec\n", Stop_time() / nloop);
35 Kill(childpid, SIGTERM);
36 exit(0);
37 }
Функция doit
2-9 Эта функция запускается родительским процессом. Мы измеряем время ее работы. Она помещает 1 байт в канал, из которого читает дочерний процесс, и считывает 1 байт из другого канала, в который сообщение помещается дочерним процессом. При этом измеряется именно то, что мы назвали задержкой, — время передачи небольшого сообщения туда и обратно.