Чтение онлайн

ЖАНРЫ

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:

2 void

3 server(void *cookie, char *argp, size_t arg_size,

4 door_desc_t *dp, size_t n_descriptors)

5 {

6 char c;

7 Door_return(&c, sizeof(char), NULL, 0);

8 }

9 int

10 main(int argc, char **argv)

11 {

12 int i, nloop, doorfd, contpipe[2];

13 char c;

14 pid_t childpid;

15 door_arg_t arg;

16 if (argc != 3)

17 err_quit("usage: lat_door <pathname> <#loops>");

18 nloop = atoi(argv[2]);

19 unlink(argv[1]);

20 Close(Open(argv[1], O_CREAT | O_EXCL | O_RDWR, FILE_MODE));

21 Pipe(contpipe);

22 if ((childpid = Fork) == 0) {

23 doorfd = Door_create(server, NULL, 0);

24 Fattach(doorfd, argv[1]);

25 Write(contpipe[1], &c, 1);

26 for(;;) /*
дочерний процесс = сервер */

27 pause;

28 exit(0);

29 }

30 arg.data_ptr = &c; /* родительский процесс = клиент */

31 arg.data_size = sizeof(char);

32 arg.desc_ptr = NULL;

33 arg.desc_num = 0;

34 arg.rbuf = &c;

35 arg.rsize = sizeof(char);

36 if (Read(contpipe[0], &c, 1) != 1) /* ждем создания */

37 err_quit("pipe read error");

38 doorfd = Open(argv[1], O_RDWR);

39 Door_call(doorfd, &arg); /* запуск */

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 /* блокировка взаимного исключения */

Поделиться с друзьями: