Главная страница Взаимодействие нетривиальных процессов Листинг Г.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 {
|
© 2000 - 2025 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |