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

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

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 );



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