Druzya.org
Возьмемся за руки, Друзья...
 
 
Наши Друзья

Александр Градский
Мемориальный сайт Дольфи. 
				  Светлой памяти детей,
				  погибших  1 июня 2001 года, 
				  а также всем жертвам теракта возле 
				 Тель-Авивского Дельфинариума посвящается...

Библиотека :: Компьютеры и Программирование :: Котеров Д. В. - Самоучитель PHP 4
<<-[Весь Текст]
Страница: из 287
 <<-
 
овольно-таки неудачен, и вот по какой причине. Представьте, что 
про- 
цессов-читателей много, а писателей — мало, и к тому же писатели еще и 
вызывают- 
ся, скажем, раз в пару минут, а не постоянно, как читатели. В случае 
использования 
исключительной блокировки для процессов-читателей, довольно интенсивно обра- 
щающихся к файлу, мы очень скоро получим целый их рой, висящий, недовольно 
гудя, в очереди, пока очередному процессу разрешат читать. Но ведь никакой 
"ава- 
рии" не случится, если один и тот же файл будут читать и сразу все процессы 
этого 
роя, правда? Ведь чтение из файла его не изменяет. Итак, предоставив 
исключитель- 
ную блокировку для читателей, мы потенциально получаем проблемы с производи- 
тельностью, перерастающие в катастрофу, когда процессов-читателей становится 
больше некоторого определенного порога. 
Второй (и лучший) способ подразумевает использование разделяемой блокировки. 
Процесс, который устанавливает этот вид блокировки, будет приостановлен только 
в 
одном случае: когда активен другой процесс, установивший исключительную блоки- 
ровку. В нашем примере процессы-читатели будут "поставлены в очередь" только 
тогда, когда активизируется процесс-писатель. И это правильно. Посудите сами: 
за- 
чем зажигать красный свет на перекрестке, если поперечного движения заведомо 
нет? 
Теперь давайте посмотрим на разделяемую блокировку читателей с точки зрения 
процесса-писателя. Что он должен делать, если кто-то читает из файла, в который 
он 
как раз собирается записывать? Очевидно, он должен дождаться, пока читатель не 
закончит работу. Иными словами, вызов flock($f,LOCK_EX) обязан подождать, 
пока активна хотя бы одна разделяемая блокировка. Это и происходит в 
действитель- 
ности. 
Возможно, вам на ум пришла аналогия с перекрестком, по одной дороге кото- 
рого движется почти непрерывный поток машин, и поперечное движение при 
этом блокируется навсегда, — так что у водителей нет никаких шансов про- 
биться через сплошной поток. В реальном мире это действительно иногда про- 
исходит (потому-то любой светофор всегда представляет собой исключитель- 
ную блокировку), но только не в мире PHP. Дело в том, что, если почти всегда 
активна разделяемая блокировка, операционная система все равно так рас- 
пределяет кванты времени, что в некоторые из них можно "включить" исключи- 
тельную блокировку. То есть "поток машин" становится не сплошным, а с "про- 
белами" — ровно такого размера, чтобы в них могли "прошмыгнуть" машины, 
едущие в перпендикулярном направлении. 
В листинге 15.3 представлена модель процесса, использующего разделяемую блоки- 
ровку. 
Листинг 15.3. Модель процесса с разделяемой блокировкой 
 
Устанавливайте разделяемую блокировку, когда вы собираетесь только читать 
из файла, не изменяя его. Всегда используйте при этом режим открытия r, и 
никакой другой. Снимайте блокировку так рано, как только сможете. 
Блокировки с запретом "подвисания" 
Как следует из описания функции flock(), к ее второму параметру можно приба- 
вить константу LOCK_NB для того, чтобы функция не ожидала, когда программа мо- 
жет "двинуться в путь", а сразу же возвращала управление в основную программу. 
Это может пригодиться, если вы не хотите, чтобы ваш сценарий бесполезно 
простаи- 
вал, ожидая, пока ему разрешат обратиться к файлу. В эти моменты, возможно, 
луч- 
ше будет заняться какой-нибудь полезной работой — например, почистить времен- 
ные файлы, память, или же просто сообщить пользователю, что файл заблокирован, 
чтобы он подождал и не думал, что программа зависла. Вот пример использования 
исключительной блокировки в совокупности с LOCK_NB: 
$f=fopen("file.txt","a+"); 
while(!flock($f,LOCK_EX+LOCK_NB)) { 
echo "Пытаемся получить доступ к файлу 
"; sleep(1); // ждем 1 секунду } // Работаем Эта программа основывается на том факте, что выход из fl
 
<<-[Весь Текст]
Страница: из 287
 <<-