Главная страница Взаимодействие нетривиальных процессов 20 Senijnit(&sem2, 1. 0); 21 a1arni(2): 22 if (sem wait(&sem2) == 0) 23 printf( seni wait returned 0?\n ); 24 else 25 err ret( seni wait error ); 26 Seni destroy(&sem2): 27 exit(O); 28 } 29 static void 30 sig alrm(int signo) 31 { 32 printf( SIGALRM caughtVn ): 33 return; 34 } Реализация с использованием FIFO возвращает EINTR, поскольку semwait блокируется в вызове read, который должен возвращать такую ошибку. Реализация с использованием отображения в память ошибки не возвращает, поскольку sem wait блокируется в вызове pthread cond wait, а эта функция не возвращает такой ошибки. Реализация с использованием семафоров System V возвращает ошибку EINTR, поскольку sem wait блокируется в вызове semop, которая возвращает эту ошибку. 9. Реализация с использованием каналов (листинг 10.25) является защищенной, поскольку таковой является операция wri te. Реализация с отображением в память защищенной не является, поскольку функции pthreadXXX не являются защищенными и не могут вызываться из обработчика сигналов. Реализация с семафорами System V (листинг 10.41) также не является защищенной, поскольку semop не является защищенной функцией согласно Unix 98. Глава 11 1. Нужно изменить только одну строку: < semid = Semget(Ftok(argv[optind], 0), О, 0): > semid = ato1(argv[optind]); 2. Вызов ftok вернет ошибку, что приведет к завершению работы обертки Ftok. Функция ту 1оск могла бы вызывать ftok перед semget, проверять, не возвращается ли ошибка ENOENT, а затем создавать файл, если он не существует. Глава 12 1. Размер файла увеличится еще на 4096 байт (до 36 864), но обращение к новому концу файла (36 863) может привести к отправке сигнала SIGSEGV, поскольку размер области отображения в памяти равен 32 768 байт. Причина, по которой мы говорим может , а не должен , - в неопределенности размера страницы памяти. 2. На рис. Г.1 показана схема с очередью сообщений System V, а на рис. Г.2 - с очередью сообщений Posix. Вызовы memcpy в отправителе происходят внутри функций mq send (листинг 5.26), а в получателе - внутри mq receive (листинг 5.28). получатель очередь сообщений System V Рис. Г. 1. Отправка сообщений в очередь System V отправитель получатель mejncpy () очередь Posix в разделяемой памяти адресное пространство получателя твтсру () отправитель адресное пространство отправителя процесс ядро алгоритмы ядра для работы с виртуальной памятью обеспечивают синхронизацию содержимого файла и области отображения Рис. Г.2. Отправка сообщений через очередь Posix, реализованную с mmap 3. Любой вызов read для /dev/zero возвращает запрошенное количество нулей. Данные, помещаемые в этот файл, попросту сбрасываются (аналогично /dev/ null). 4. В результате в файле получится 4 байта - все нули (предполагается 32-разрядное целое). 5. В листинге Г.7 приведен текст нашей программы. Листинг Г.7. Использование select с очередями System V shm/svmsgread.c 1 #include unpipc.h 2 #define MAXMSG (8192 + sizeof(long)) 3 int 4 maiп(int argc. char **argv) 6 int pipel[2]. pipe2[2], mqid; 7 char c; 8 pid t childpid; 9 fd set rset: 10 ssi2e t n. nread: 11 struct msgbuf *buff: 12 if (argc != 2) 13 err quit( usage: svmsgread <pathname> ); 14 Pipe(pipel); /* двусторонняя связь */ 15 Pipe(pipe2); 16 buff = f shm(MAXMSG); /* неименованная разделяемая память */ 17 if ( (childpid = ForkO) == 0) { 18 C1ose(pipel[l]): /* child */ 19 Close(pipe2[0]): 20 mqid = Msgget(Ftok(argv[l]. 0). MSG R): 21 for ( : : ) { 22 /* блокируется в ожидании, извещает родительский процесс */ 23 nread = Msgrcv(mqid. buff, MAXMSG. О, 0): 24 Write(pipe2[l], &nread, sizeof(ssi2e t)): 25 /* ожидает разрешения родительского процесса */ 26 if ( (n Read(pipel[0], &c, D) != 1) 27 err quit( chi1d: read on pipe returned Xd . n); 28 } 29 exit(O): 30 ) /* $$.bp$$ */ 31 /* parent */ 32 C1ose(pipel[0]): 33 C1ose(pipe2[l]): 34 FD ZERO(&rset): 35 FD SET(pipe2[0], &rset): 36 for ( ; : ) { 37 if ( (n - se1ect(pipe2[0] + 1, Srset, NULL, NULL, NULL)) != 1) 38 err sys( select returned %й . n); 39 if (FD ISSET(pipe2[0], &rset)) { 40 n = Read(pipe2[0], &nread, si2eof(ssi2e t)); /* *INDENT-OFF* */ 41 if (n != Sizeof(ssize t)) 42 err quit( parent: read on pipe returned Xd . n); /* *INDENT-ON* */ 43 printf( read d bytes, type = ld\n , nread, buff->mtype): 44 Write(pipel[l], &c, 1): 45 } else 46 err quit( pipe2[0] not ready );
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |