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

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

52 53 54 55

( (п = MsgrcvCmsqid, buf. xfersize - sizeof(long). О, 0)) > 0)) nbytes -= n + sizeof(long);

Программа измерения полосы пропускания дверей

Программа измерения полосы пропускания интерфейса дверей сложнее, чем предыдущие, поскольку нам нужно вызвать fork перед созданием двери. Родительский процесс создает дверь и с помощью канала оповещает дочерний процесс о том, что ее можно открывать.

Другое изменение загслючается в том, что в отличие от рис. А.7 функция reader не принимает данные. Данные принимаются функцией server, которая является процедурой сервера для данной двери. На рис. А.8 изображена схема программы.

родительский процесс

дочерний процесс

процедура сервера

измеряется время работы данной функции

main ( ) {

Pipe (contpipe);

if (Forl< () = = 0) { --

doorfd = Door create (); Fattach (); Write (contpipe [1],); reader ( ): exit (0);


server ( ) {

if (end of data)

Write (contpipe [0],); Door return i

reader ( )

Write (contpipe [1],); Read (contpipe [1],); -<-

forl< ()


mam i

if(Fork() = = 0) { Read (contpipe [0],) doorfd = Open ( ); writer (); exit (0): }

Read (contpipe [0],); while (more to send);

Wnte (datapipe [1],) Door call ( );

Рис. A.8. Схема программы измерения полосы пропускания дверей

Поскольку двери поддерживаются только в Solaris, мы упростим программу, предполагая наличие двустороннего канала (раздел 4.4).

Еще одно изменение вызвано фундаментальным различием между передачей сообщений и вызовом процедуры. В программе, работавшей с очередью сообщений Posix, например, записывающий процесс просто помещал сообщения в оче-



редь в цикле, что осуществляется асинхронно, В какой-то момент очередь будет заполнена или записывающий процесс будет просто приостановлен, и тогда считывающий процесс получит сообщения. Если, например, в очередь помещается 8 сообщений и записывающий процесс помещал в нее 8 сообщений каждый раз, когда получал управление, а считывающий процесс считывал 8 сообщений, отправка N сообщений требовала N/4 перегслючения контекста. Интерфейс дверей является синхронным: вызывающий процесс блокируется каждый раз при вызове doorcal 1 и не может возобновиться до тех пор, пока сервер не завершит работу. Передача N сообщений в этом случае требует N/2 переключений контекста. С той же проблемой мы столкнемся при измерении полосы пропускания вызовов RPC. Несмотря на увеличившееся количество переключений контекста, из рис. А. 1 следует, что двери обладают наибольшей полосой пропускания при размере сообщений не более 25 Кбайт.

В листинге А.9 приведен текст функции main нашей программы. Функции writer, server и reader приведены в листинге А.10.

Листинг А.9. Функция main измерения полосы пропускания интерфейса дверей

bench/bw door.c

1 #include unpipc.h

2 void reader(int. int):

3 void writer(int):

4 void server(void *. char *. size t. door desc t *. size t):

5 void *buf:

6 int totalnbytes. xfersize. contpipe[2]:

7 int

8 mainCint argc. char **argv)

10 int i. nloop. doorfd:

11 char c:

12 pid t childpid:

13 ssize t n:

14 if (argc != 5)

15 err quit( usage: bw door <pathname> <#loops> <#mbytes> <#bytes/write> ):

16 nloop = atoi(argv[2]):

17 totalnbytes = atoi(argv[3]) * 1024 * 1024:

18 xfersize = atoi(argv[4]):

19 buf = Valloc(xfersize):

20 TouchCbuf. xfersize):

21 unlink(argv[l]):

22 Close(Open(argv[l], OJREAT OJXCL OJDWR, FILE MODE)):

23 Pipe(contpipe); /* предполагается наличие двустороннего канала SVR4 */

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

25 /* дочерний процесс = клиент */

26 if ( (n = Read(contpipe[0], &c, D) != 1)

27 err quit( child: pipe read returned %й , n);

28 doorfd = Open(argv[l], OJDWR):



29 writer(doorfd):

30 exit(O):

31 }

32 /* родительский процесс = сервер */

33 doorfd = Door create(server. NULL. 0);

34 FattachCdoorfd. argv[l]):

35 Write(contpipe[l]. &c. 1); /* уведомление о готовности двери */

36 Start time():

37 for (i = 0: 1 < nloop: i++)

38 readerCdoorfd. totalnbytes);

39 printfCbandwidth: .3f MB/sec\n .

40 totalnbytes / Stop time() * nloop);

41 kilKchildpid. SIGTERM):

42 unlink(argv[l]);

43 exitCO);

44 }

Листинг A.I 0. Функции writer, server, reader для интерфейса дверей

bench/bw door.c

45 void

46 writerCint doorfd)

47 {

48 int ntowrite;

49 door arg t arg;

50 arg.desc ptr = NULL: /* дескрипторы не передаются */

51 arg.desc num = 0;

52 arg.rbuf = NULL: /* значения не возвращаются */

53 arg.rsize = 0;

54 for ( ; ; ) {

55 Read(contpipe[0]. Sntowrite. sizeof(ntowrite));

56 while (ntowrite > 0) {

57 arg.data ptr = buf;

58 arg.data size = xfersize;

59 Door call(doorfd. &arg);

60 ntowrite -= xfersize;

61 }

62 }

63 }

64 static int ntoread. nread;

65 void

66 server(void *cookie. char *argp, size t argsize.

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

68 {

69 char c;

70 nread += arg size:

71 if (nread >= ntoread)

72 Write(contpipe[0]. &c. 1); /* запись закончена */

73 Door return(NULL. 0. NULL. 0); л

продолжение



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.
Копирование материалов разрешено исключительно при условии цититирования.