Читать «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 байт из другого канала, в который сообщение помещается дочерним процессом. При этом измеряется именно то, что мы назвали задержкой, — время передачи небольшого сообщения туда и обратно.