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

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

Создание двух каналов

18-19 Создаются два канала: contp1pe[0] и contp1pe[l] используются для синхронизации процессов перед началом передачи, а datapipe[0] и datap1pe[l] используются для передачи самих данных.

Вызов fork

20-31 Создается дочерний процесс, вызывающий функцию writer, а родительский процесс в это время вызывает функцию reader. Функция reader вызывается п1 оор раз. Функция start time вызывается непосредственно перед началом цикла, а stop time - сразу после его окончания. Эти функции даны в листинге А.З. Полоса пропускания представляет собой количество байтов, переданных за все проходы цикла, поделенное на время, затраченное на передачу (stop time возвращает количество микросекунд, прошедшее с момент запуска start t1me). Затем дочерний процесс завершается сигналом SIGTERM и программа завершает свою работу.

Вторая половина программы приведена в листинге А.2. Она состоит из функций reader и writer.

Листинг А.2. Функции reader и writer

bencli/bw pipe.cvoid

33 void

34 writer(int contfd. int datafd)

35 {

36 int ntowrite:

37 for ( : ; ) {

38 ReadCcontfd. Sntowrite. sizeof(ntowrite)):

39 wliile (ntowrite > 0) {

40 Write(datafd. buf. xfersize);

41 ntowrite -= xfersize:

42 }

43 }

44 }

45 void

46 reader(int contfd. int datafd. int nbytes)

47 {

48 ssize t n;

49 Write(contfd. Snbytes. sizeof(nbytes));

50 wliile ((nbytes > 0) &&

51 ( (n = Read(datafd. buf. xfersize)) > 0)) {

52 nbytes -= n:

53 }

54 }

Функция writer

33-44 Функция writer представляет собой бесконечный цикл, вызываемый дочерним процессом. Он ожидает сообщения родительского процесса о готовности к приему данных, считывая целое число из управляющего канала. Это целое чис-



ло определяет количество байтов, которое будет записано в канал данных. При получении этого числа дочерний процесс записывает данные в канал, отправляя их родителю. За один вызов write записывается xfersize байтов.

Функция reader

45-54 Эта функция вызывается родительским процессом в цикле. Каждый раз при вызове функции в управляющий канал записывается целое число, указывающее дочернему процессу на необходимость помещения соответствующего количества данных в канал данных. Затем функция вызывает read в цикле до тех пор, пока не будут приняты все данные.

Текст функций start time, stop time и touch приведен в листинге А.З.

Листинг А.З. Функции startsime, stop time и touch

lib/timing.с

1 #include unpipc.h

2 static struct timeval tv start, tv stop;

3 int

4 start time(void)

6 return(gettimeofday(&tv start. NULL)):

8 double

9 stop time(void)

10 {

11 double clockus;

12 if (gettimeofday(&tv stop, NULL) == -1)

13 return(O.O):

14 tv sub(&tv stop, &tv start):

15 clockus = tv stop.tv sec * 1000000.0 + tv stop.tv usec:

16 return(clockus);

17 }

18 int

19 touchCvoid *vptr. int nbytes)

20 {

21 char *cptr:

22 static int pagesize = 0:

23 if (pagesize == 0) {

24 errno = 0:

25 #ifdef SC PAGESIZE

26 if ( (pagesize = sysconf( SC PAGESIZE)) == -1)

27 return(-l):

28 #else

29 pagesize = getpagesizeO: /* BSD */

30 #endif

31 )

32 cptr = vptr:

33 while (nbytes > 0) {



ПРИМЕЧАНИЕ

Обратите внимание, что в программе приходится указывать максимальное количество сообщений в очереди при ее создании. Мы указываем значение 4. Размер канала IPC может влиять на производительность, потому что записывающий процесс может отправить это количество сообщений, прежде чем будет заблокирован в вызове mq send, что приведет к переключению контекста на считывающий процесс. Следовательно, производительность программы зависит от этого магического числа. Изменение его

34 *cptr = 1:

35 cptr += pagesize:

36 nbytes -= pagesize;

37 )

38 return(O):

39 }

Текст функции tv sub приведен в листинге А.4. Она осуществляет вычитание двух структур timeval, сохраняя результат в первой структуре.

Листинг А.4. Функция tv sub: вычитание двух структур timeval

lib/tv sub.c

1 #include unpipc.h

2 void

3 tv sub(struct timeval *out. struct timeval *in)

4 {

5 if ( (out->tv usec -= in->tv usec) < 0) { /* out -= in */

6 --out->tv sec;

7 out->tv usec += 1000000;

9 out->tv sec -= in->tv sec; 10 }

Ha компьютере Sparc под управлением Solaris 2.6 при выполнении программы пять раз подряд получим следующий результат:

Solaris % bw pipe 5 10 65536 bandwidth: 13.722 MB/sec Solaris % bw pipe 5 10 65536 bandwidth: 13.781 MB/sec Solaris % bw pipe 5 10 65536 bandwidth: 13.685 MB/sec Solaris % bw pipe 5 10 65536 bandwidth: 13.665 MB/sec Solaris % bw pipe 5 10 65536 bandwidth: 13.584 MB/sec

Каждый раз мы задаем пять циклов, 10 Мбайт за цикл и 65 536 байт за один вызов write или read. Среднее от этих пяти результатов даст величину 13,7 Мбайт в секунду, приведенную в табл. А.2.

Измерение полосы пропускания очереди сообщений Posix

в листинге А.5 приведена функция mai п программы, измеряющей полосу пропускания очереди сообщений Posix. Листинг А.6 содержит функции reader и writer. Эта программа устроена аналогично предыдущей, измерявшей полосу пропускания канала.



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