Главная страница  Взаимодействие нетривиальных процессов 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 [ 161 ] 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

Листинг А. 16 (продолжение)

31 Start time();

32 for (i = 0; i < nloop; i++)

33 doit(msgid);

34 printfC latency: ,3f usec\n , Stop time() / nloop);

35 KilKchildpid, SIGTERM);

36 MsgctKmsgid, IPC RMID, NULL);

37 exitCO):

38 }

Мы создаем одну очередь, по которой сообщения передаются в обоих направлениях. Сообщения с типом 1 передаются от родительского процесса дочернему, а сообщения с типом 2 - в обратную сторону. Четвертый аргумент при вызове msgrcv в функции doit имеет значение 2, что обеспечивает получение сообщений только данного типа. Аналогично в дочернем процессе четвертый аргумент msgrcv имеет значение 1,

ПРИМЕЧАНИЕ -

В разделах 9,3 и 11,3 мы отмечали, что многие структуры, определенные в ядре, нельзя инициализировать статически, поскольку стандарты Posix,l и Unix 98 гарантируют лишь наличие определенных полей в этих структурах, но не определяют ни их порядок, ни наличие других полей, В этой программе мы инициализируем структуру msgbuf статически, поскольку очереди сообщений System V гарантируют, что эта структура содержит поле типа сообщения long, за которым следуют передаваемые данные.

Программа измерения задержки интерфейса дверей

Программа измерения задержки для интерфейса дверей дана в листинге А, 17. Дочерний процесс создает дверь и связывает с ней функцию server. Родительский процесс открывает дверь и вызывает door cal 1 в цикле, В качестве аргумента передается 1 байт данных, и ничего не возвращается.

Листинг А. 17. Программа измерения задержки интерфейса дверей

bench/lat door.c

1 #include unpipc.h

2 void

3 serverCvoid *cookie, char *argp, size t arg size.

4 door desc t *dp. size t n descriptors)

6 char c;

7 Door return(&c. sizeof(char). NULL. 0);

9 int

10 mainCint 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: 1 at door <pathname> <#l[oops> );

18 nloop = atoi(argv[2]):

19 unlink(argv[l]):

20 Close(Open(argv[l], 0 CREAT OJXCL 0 RDWR. FILE MODE)):

21 Pipe(contpipe);

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

23 doorfd = Door create(server. NULL. 0):

24 Fattach(doorfd. argv[l]);

25 Write(contpipe[l]. &c. 1):

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

27 pauseO:

28 exit(O):

29 }

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

31 arg.data size = sizeof(char);

32 arg.descjDtr = 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(rgv[l], 0 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 KilKchildpid, SIGTERM);

45 unlink(argv[l]);

46 exit(O);

47 }

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

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

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

bench/lat sunrpc client.c

1 #include unpipc.h

2 #include lat sunrpc.h продолжение



Листинг А. 18 (продолжение)

3 int

4 mainCint argc, char **argv)

6 int i, nloop:

7 CLIENT *cl;

8 struct timeval tv:

9 if Cargc !- 4)

10 err quitC usage: lat sunrpc client <hostname> <#loops> <protocol> ):

11 nloop - atoiCargv[2]):

12 cl - Clnt createCargv[l], BW SUNRPC PROG, BW SUNRPC VERS, argv[3]):

13 tv,tv sec - 10:

14 tv,tv usec - 0:

15 Start timeC):

16 for Ci = 0: i < nloop: i++) {

17 if Cclnt callCcl, NULLPROC, xdr void, NULL,

18 xdr void, NULL, tv) !- RPC SUCCESS)

19 err quitC *s , clnt sperrorCcl, argv[l])):

20 }

21 printfC latency: .3f usec\n , StopJimeC) / nloop):

22 exitCO):

23 }

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

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

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

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

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

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

bench/incr pxmutexl.с

1 #include unpipc.h

2 #define MAXNTHREADS 100

3 int nloop;

4 struct {



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 [ 161 ] 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.