Читаем UNIX Network Programming. Volume 2 Second Edition. Interprocess Communications полностью

40  Start_time;

41  for (i = 0; i nloop; i++)

42   Door_call(doorfd, arg);

43  printf("latency: %.3f usec\n", Stop_time / nloop);

44  Kill(childpid, SIGTERM);

45  unlink(argv[1]);

46  exit(0);

47 }

Программа измерения времени задержки Sun RPC

Для измерения времени задержки Sun RPC мы напишем две программы: клиент и сервер, аналогично измерению полосы пропускания. Мы используем старый файл спецификации RPC, но на этот раз клиент вызывает нулевую процедуру сервера. Вспомните упражнение 16.11: эта процедура не принимает никаких аргументов и ничего не возвращает. Это именно то, что нам нужно, чтобы определить задержку. В листинге А.18 приведен текст клиента. Как и в решении упражнения 16.11, нам нужно воспользоваться clnt_call для вызова нулевой процедуры; в заглушке клиента отсутствует необходимая заглушка для этой процедуры.

Листинг А.18. Клиент Sun RPC для измерения задержки

//bench/lat_sunrpc_client.с

1  #include "unpipc.h"

2  #include "lat_sunrpc.h"


3  int

4  main(int argc, char **argv)

5  {

6   int i, nloop;

7   CLIENT *cl;

8   struct timeval tv;

9   if (argc != 4)

10   err_quit("usage: lat_sunrpc_client hostname #loops protocol");

11  nloop = atoi(argv[2]);

12  cl = Clnt_create(argv[1], BW_SUNRPC_PROG, BW_SUNRPC_VERS, argv[3]);

13  tv.tv_sec = 10;

14  tv.tv_usec = 0;

15  Start_time;

16  for (i = 0; i nloop; i++) {

17   if (clnt_call(cl, NULLPROC, xdr_void, NULL,

18    xdr_void, NULL, tv) != RPC_SUCCESS)

19    err_quit("%s", clnt_sperror(cl, argv[1]));

20  }

21  printf("latency: %.3f usec\n", Stop_time / nloop);

22  exit(0);

23 }

Мы компилируем сервер с функцией, приведенной в листинге А.13, но она все равно не вызывается. Поскольку мы используем rpcgen для построения клиента и сервера, нам нужно определить хотя бы одну процедуру сервера, но мы не обязаны ее вызывать. Причина, по которой мы используем rpcgen, заключается в том, что она автоматически создает функцию main сервера с нулевой процедурой, которая нам нужна.

А.5. Синхронизация потоков: программы

Для измерения времени, уходящего на синхронизацию при использовании различных средств, мы создаем некоторое количество потоков (от одного до пяти, согласно табл. А.4 и А.5), каждый из которых увеличивает счетчик в разделяемой памяти большое количество раз, используя различные формы синхронизации для получения доступа к счетчику.

Взаимные исключения Posix

В листинге А.19 приведены глобальные переменные и функция main пpoгрaммы, измеряющей быстродействие взаимных исключений Posix.

Листинг А.19. Глобальные переменные и функция main для взаимных исключений Posix

//bench/incr_pxmutex1.с

1  #include "unpipc.h"

2  #define MAXNTHREADS 100


3  int nloop;

4  struct {

5   pthread_mutex_t mutex;

6   long counter;

7  } shared = {

8   PTHREAD_MUTEX_INITIALIZER

9  };

10 void *incr(void *);


11 int

12 main(int argc, char **argv)

13 {

14  int i, nthreads;

15  pthread_t tid[MAXNTHREADS];

16  if (argc != 3)

17   err_quit("usage: incr_pxmutex1 #loops #threads");

18  nloop = atoi(argv[1]);

19  nthreads = min(atoi(argv[2]), MAXNTHREADS);

20  /* блокировка взаимного исключения */

21  Pthread_mutex_lock(shared.mutex);

22  /* создание потоков */

23  Set_concurrency(nthreads);

24  for (i = 0; i nthreads; i++) {

25   Pthread_create(tid[i], NULL, incr, NULL);

26  }

27  /* запуск таймера и разблокирование взаимного исключения */

28  Start_time;

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже