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

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

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

48 KilKchildpid, SIGTERM);

49 exit(O);

50 }

Глава 13

1. в листинге Г.8 приведен текст измененной версии листинга 12.6, а в листинге Г.9 - текст новой версии листинга 12.7. Обратите внимание, что в первой программе мы устанавливаем размер объекта вызовом ftruncate; Iseek и write использовать для этого нельзя.

Листинг Г.8. Отображение с точным указанием размера файла

pxshm/testl.c

1 #inc1ude unpipc.h

2 int

3 main(int argc, char **argv) 4 {

5 int fd. i;

6 char *ptr;

7 size t shmsize, inmapsize, pagesize;

8 if (argc != 4)

9 err quit( usage; testl <name> <shmsize> <mniapsize> );

10 shmsize = atoi(argv[2]);

11 mmapsize = atoi(argv[3]);

12 /* открываем shm; создание или урезание; установка размера */

13 fd = Shm open(Px ipc name(argv[l]), 0 RDWR 0 CREAT OJRUNC,

14 ~ FILE MODE);

15 Ftruncate(fd, shmsize); /* $$.bp$$ */

16 ptr = Mmap(NULL, mmapsize, PROT READ PROT WRITE. MAP SHARED, fd. 0);

17 Close(fd);

18 pagesize = Sysconf( SC PAGESIZE);

19 printfCPAGESIZE = 1d\n . (long) pagesize);

20 for (i = 0; i < max(shmsize, mmapsize); i += pagesize) {

21 printf( ptr[ d] = d\n . i. ptr[i]);

22 ptr[i] = 1:

23 printf( ptr[M] = %й\п . i + pagesize - 1, ptr[i + pagesize - 1]);

24 ptr[i + pagesize - 13 = 1;

25 }

26 printf( ptr[ d] = d\n , i, ptr[i]);

27 exit(O);

28 }

Листинг Г.9. Отображение в память с возможностью роста файла

pxshm/test2.c

1 #inc1ude unpipc.h

2 #define FILE test.data



3 #define SIZE 32768

4 int

5 mainCint argc. char **argv)

7 int fd, i:

8 char *ptr:

9 /* создаем или урезаем, отображаем */

10 fd = Shm open(Px ipc name(FILE). 0 RDWR 0 CREAT OJRUNC. FILEJODE):

11 ptr = Mmap(NULL, SIZE, PROTJEAD PROTJRITE, MAPJHARED, fd. 0);

12 for (i = 4096; i <= SIZE: i += 4096) {

13 printf( setting shm size to %й\п . i);

14 FtruncateCfd, i);

15 printf( ptr[ d] %а\п . i-1, ptr[i-l]):

16 }

17 exit(O):

18 )

2. Одна из возможных проблем при использовании *ptr++ заключается в том, что указатель, возвращенный тар, изменяется, что может помешать впоследствии вызвать munmap. Если этот указатель еще понадобится, лучше его сохранить или вовсе не изменять.

Глава 14

1. Нужно изменить только одну строку: 13с 13

< id = Shmget(Ftok(argv[l], 0), О, SVSHMJORE); > id = atol(argv[l]);

Глава 15

1. Аргументы будут иметь размер data ji ze + (descjumxsi zeof (door desc J)) байт.

2. Вызывать fstat не нужно. Если дескриптор не указывает на дверь, вызов door i nf о возвращает ошибку EBADF:

Solaris % doorinfo /etc/passwd

doorjnfo error: Bad file number

3. Документация содержит неверные сведения. Стандарт Posix утверждает, что функция sleep приведет к приостановке вызвавшего потока.

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

5. При завершении door jal 1 из-за перехвата сигнала сервер следует уведомить об этом, поскольку поток, работающий с этим клиентом, получит запрос на отмену выполнения. В связи с листингом 15.18 мы говорили, что отмена для



создаваемых библиотекой потоков по умолчанию отключена, следовательно, поток завершен не будет. Вместо этого происходит досрочный возврат из вызова sleep(6) в процедуре сервера, но она продолжает выполняться.

6. Вот что мы увидим:

Solaris % servere /tmp/door6

rny thread: created sever thread 4 door bind error: Bad file number

Запустив сервер 20 раз подряд, мы ползшм 5 сообщений об ошибке. Предсказать такую ошибку заранее нельзя.

7. Нет. Все, что нужно, - включать возможность отмены каждый раз при вызове процедуры сервера, как мы делали в листинге 15.26. Хотя в этом случае и приходится вызывать pthread setcancel state каждый раз при запуске процедуры сервера, накладные расходы, скорее всего, будут невелики.

8. Чтобы проверить это, изменим код одного из серверов (скажем, из листинга 15.6) так, чтобы он вызывал door revoke из процедуры сервера. Поскольку аргументом door revoke является дескриптор двери, его придется сделать глобальным. Вот что получится при запуске клиента (из листинга 15.1) два раза подряд:

Solaris % clients /tmp/door8 88

result: 7744

Solaris % client8 /tmp/door8 99

door can error: Bad file number

Первый вызов завершается успешно, что подтверждает наше предположение насчет door revoke. Второй вызов возвращает ошибку EBADF.

9. Чтобы не делать дескриптор fd глобальным, мы воспользуемся указателем cooki е, который можем передать door create и который затем будет передаваться процедуре сервера при каждом вызове. В листинге Г. 10 приведен текст сервера.

Листинг Г. 10. Использование указателя cookie для избавления от глобальных переменных

doors/server9.c

1 #include unpipc.h

2 void

3 servprocCvoid *cookie, char *dataptr. si2e t datasize.

4 door desc t *descptr, size t ndesc)

6 long arg. result;

7 Door revoke(*((int *) cookie));

8 arg = *((long *) dataptr);

9 printfC thread id Xid. arg X]d\n . pr thread id(NULL). arg);

10 result - arg * arg;

11 Door return((char *) &result, sizeof(result). NULL, 0);

12 }

13 int

14 maindnt argc, char **argv)

15 {



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