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

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

8 act.sa flags - SA SIGINFO: /* гарантирует режим реального времени */

9 if (signo == SIGALRM) {

10 #ifdef SA INTERRUPT

11 act.sa flags = SAJNTERRUPT: /* SunOS 4.x */

12 #endif

13 } else {

14 #ifdef SA RESTART

15 act.sa flags 1= SA RESTART: /* SVR4. 44BS0 */

16 #endif

17 }

18 if (sigaction(signo, &act, &oact) < 0)

19 return((Sigfunc rt *) SIGJRR):

20 return(oact.sa sigaction):

21 }

Упрощение прототипа функции с использованием typedef

1-3 в нашем заголовочном файле unpipc.h (листинг В.1) мы определяем Sigfunc rt как typedef void Sigfunc rt(int. siginfo t *. void *); Ранее в этом разделе мы говорили о том, что это прототип функции для обработчика сигнала, устанавливаемого с флагом SA SIGINFO.

Указание функции-обработчика

Структура sigaction претерпела изменения с добавлением поддержки сигна-5-7 лов реального времени: к ней было добавлено новое поле sa si gacti on: struct sigaction {

void (*sa handler)(): /* SIG OFL. SIG IGN или адрес обработчика сигнала */ sigset t sa mask: /* дополнительные блокируемые сигналы */ int sa flags; /* параметры сигналов: SA XXX */

void (*sa sigaction)(int. siginfo t. void *):

Правила действуют следующие:

ii Если в поле sa flags установлен флаг SA SIGINFO, поле sa sigaction указывает адрес функции-обработчика сигнала.

ш Если флаг SA S IGINFO не установлен, поле sa handl ег указывает адрес функции-обработчика сигнала.

Чтобы сопоставить сигналу действие по умолчанию или игнорировать его, следует установить sa handler равным либо SIG DFL, либо SIG IGN и не устанавливать флаг SA S IGINFO.

Установка SA.SIGINFO

8-17 Мы всегда устанавливаем флаг SA SIGINFO и указываем флаг SA RESTART, если перехвачен какой-либо другой сигнал, кроме SIGALRM.

5.8. Реализация с использованием отображения в память

Теперь рассмотрим реализацию очередей сообщений Posix с использованием отображения в память, взаимных исключений и условных переменных Posix.



ПРИМЕЧАНИЕ-

Взаимные исключения и условные переменные описаны в главе 7, а ввод-вывод с отображением в память - в главах 12 и 13. Вы можете отложить данный раздел до ознакомления с этими главами.

На рис. 5.2 приведена схема структур данных, которыми мы пользуемся для реализации очереди сообщений Posix. Изображенная очередь может содержать до четырех сообщений по 7 байт каждое.

В листинге 5.16 приведен заголовочный файл mqueue. ii, определяющий основные структуры, используемые в этой реализации.

Тип mqd t

Дескриптор нашей очереди сообщений является просто указателем на структуру mq i nf 0. Каждый вызов mq open выделяет память под одну такую структуру, а вызвавшему возвращается указатель на нее. Повторим, что дескриптор очереди сообщений не обязательно является небольшим целым числом, как дескриптор файла - единственное ограничение, накладываемое Posix, заключается в том, что этот тип данных не может быть массивом.

Листинг5.16. Заголовочный файл mqueue.h

/ /niy pxmsg nirap/mqueue. h

1 typedef struct niymq info *mymqd t:

2 struct niyniq attr {

3 long niq flags: /* флаг очереди : 0 NONBLOCK */

4 long mq niaxnisg; /* максимальное количество сообщениР! в очереди */

5 long niq nisgsize: /* максимальны! размер сообщения в 6aiiTax */

6 long niq curnisgs: /* количество сообщени11 в очереди */

7 }:

8 /* одна структура niymq hdr{} на очередь, в начале отображаемого фа11ла */

9 struct niymq hdr {

/* атрибуты очереди */ /* индекс первого сообщения*/ /* индекс первого пустого сообщения */

13 long mqh nwait-. /* количество заблокированных mq receive()

*потоков */

14 pid t mqh pid: /* ненулево11 РШ, если включено уведомление */

15 struct sigevent mqh event: /* для mq notify() */

16 pthread niutex t mqhjock: /* блокировка: mutex */

17 pthread cond t mqh wait: /* и условная переменная */

18 }:

19 /* один mymsg hdr{} в начале каждого сообщения */

20 struct mymsg hdr {

21 long msg next; /* индекс следующего сообщения в списке */

22 /* msg next должно быть первым полем в структуре */

23 ssize t msgjen: /* реальная длина */

24 unsigned int msg prio; /* приоритет */

25 }:

26 /* одна mymqJnfoO выделяется при каждом mq open() */

27 struct myiT4 info { продолжение

10 struct mymq attr mqh attr

11 long mqh head

12 long mqh free



mg attr{} <

I hdr{} г

sigevent{} <

pthread mutex t <

pthread cond t <


начало отображаемого в память файла

mci info{}

msg hdr

msg magic

msg flags

одна структура

для каждого вызова mq open

msg hdr{}

одно сообщение

одно сообщение

одно сообщение

одно сообщение

конец отображаемого в память файла

один отображаемый в память файл на каждую очередь сообщений

Рис. 5.2. Схема структур данных, используемых при реализации очередей сообщений Posix через отображаемый в память файл



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