Анимация
JavaScript


Главная  Библионтека 

0 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 187 188 [ 189 ] 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

К счастью, стандарт POSIX также требует, чтобы значение PIPE BUF было не менее 512 байт. Следовательно, остается лишь позаботиться о том, чтобы клиенты не пытались передавать более 512 байт за раз.

Но что если вам понадобилось зарегистрировать более 512 байт? Разделите каждое большое сообшение на несколько маленьких (менее 512 байт), снабдите каждое сообшение уникальным идентификатором клиента (например, идентификатором процесса) и организуйте их сборку на сервере. Нечто похожее происходит при разделении и сборке сообщений TCP/IP.

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

1> Смотри также-

Страницы руководтва mkfifo(8) или 7nknod(8) (если они есть); рецепт 17.6.

16.12. Совместное использование переменных в разных процессах

Проблема

Требуется организовать совместный доступ к неременным в разветвлениях или неродственных процессах.

Решение

Используйте средства SysV IPC, еслн ваша система их поддерживает.

Комментарий

Хотя средства SysV IPC (общая память, семафоры и т. д.) реже используются в межпроцессных коммуникациях, нежели каналы, именованные каналы и сокеты, они все же обладают рядом интересных свойств. Тем не менее для совместного иснользования неременной несколькими процессами обычно нельзя рассчитывать на работу с общей памятью через shmget или mmap(2). Дело в том, что Perl заново выделит память под строку тогда, когда вы этого совсем не ждете.

Проблема решается с помощью модуля IPC:;Shareable с CPAN. Умный модуль tie, общая память SysV и модуль Shareable с CPAN позволяют организовать совместный доступ к структурам данных произвольной сложности для процессов на одном компьютере. При этом процессы даже не обязаны быть родственными,

В примере 16.11 продемонстрирован несложный случай применения этого модуля.

Пример 16.11. sharetest

#/usr/bin/perl

# sharetest - совместный доступ к общим переменным в разветвлениях



16.12. Совместное использование переменных в разных процессах 585

use IPC Shareable,

Shandle = tie Sbuffer, IPC Shareable , undef, { destroy => 1 }, $SIG!INT} = sub { die $$ dying\n },

for (1 10) !

unless (Schild = fork) { # Я - потомок

die cannot fork $ unless defined Schild, squabbleO, exit,

push ©kids, Schild # Если нас интересуют идентификаторы процессов

while (1) {

print Buffer IS $buffer\n sleep 1

die Not reached ,

sub squabble { my $1 = 0, while (1) {

next If Sbuffer =~ /"$$\b/o

$handle->shlock(),

$1++

Sbuffer = $$ $1 $handle->shunlock()

Исходный процесс создает общую переменную, разветвляется на 10 потомков, а затем выводит значение буфера примерно каждую секунду в бесконечном цикле или до тех пор, пока вы не нажмете Ctrl+C.

Поскольку обработчик SIGINT был установлен до всех вызовов fork, его наследуют все потомки, которые также уничтожаются при прерывании группы процессов. Сигналы с клавиатуры передаются целой группе процессов, а не одному процессу.

Что же происходит в squabble? Потомки разбираются, кому из них удастся обновить общую переменную. Каждый порожденный процесс смотрит, изменилось ли состояние переменной с момента последнего визита. Если буфер начинается с его собственной сигнатуры (идентификатора процесса), процесс не трогает его. Если буфер был изменен кем-то другим, процесс блокирует общую переменную вызовом специального метода для манипулятора, полученного от tie, обновляет ее и снимает блокировку.

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

Шаблон /"$$\Ь/о вьилядит подозрительно, поскольку /о указывает на однократную компиляцию шаблона, а переменная $$ меняется при разветвлении. Впрочем,



значение фиксируется не во время компиляции программы, а при первой компиляции шаблона в каждом процессе, во время жизни которого $$ остается ностоян-пым.

Модуль IPC::Shareable также поддерживает совместное использование переменных не-родственньши процессами на одном компьютере. За подробностями обращайтесь к документации.

1> Смотри также-

Описание функций semctl, semget, semop, shmctl, shmget, shmread и shmwrite в perlfunc{\y, документация no модулю IPC::Shareable с CPAN.

16.13. Получение списка сигналов

Проблема

Вы хотите знать, какие сигналы поддерживаются вашей операционной системой.

Решение

Если ваш командный интерпретатор поддерживает встроенную команду kill -/, используйте ее:

% kill -1

HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM CHLO CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR

Чтобы сделать то же самое только на Perl версии 5 004 и выше, выведите ключи хэша %SIG:

% perl -е print ]oin( , keys %SIG) \n

XCPU ILL QUIT STOP EMT ABRT BUS USR1 XFSZ TSTP INT lOT USR2 INFO TTOU ALRM KILL HUP URG PIPE CONT SEGV VTALRM PROF TRAP 10 TERM WINCH CHLO FPE TTIN SYS

До выхода версии 5,004 приходилось использовать модуль Config:

% perl -MConfig -е print SConfig{sig name}

ZERO HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU 10 XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2 lOT

Комментарий

Если вы работаете в Perl версии младше 5.004, для получения списка сигналов вам также придется использовать @signame и %signo модуля Config, поскольку конструкция keys %SIG в ранних версиях еще не реализована.

Следующий фрагмент извлекает имена и номера доступных сигналов из стандартного модуля Config.pm. Индексирование @signame по номеру дает имя сигнала, а индексирование %signo по имени - номер сигнала.



0 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 187 188 [ 189 ] 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242