Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Кэширование на файлах или загадочный flock
Форумы портала PHP.SU » » Работа с файловой системой и файлами » Кэширование на файлах или загадочный flock

Страниц (2): [1] 2 »
 

1. Самогонщик - 28 Ноября, 2012 - 19:01:41 - перейти к сообщению
Вопрос:
Насколько сильном можно надеяться на то, что функция flock работает как надо и что значит, если она вернула false? везде ли я могу надеяться на то, что доступ к заблокированному ресурсу будет последовательным?

Лирика:
Иногда мне хочется странного, вот в данных момент захотел написать модуль кэширования и конечно же не простой, а фильтипёрстовый. Для кэширования можно использовать разделяемый файл, но к нему одновременно могут обращаться несколько нитей...

LEVEL UP! Значит нужно делать блокирование файла на время чтения/записи, но если кэш протух, то несколько нитей могут полезь за одними и теми же данными в базу...

LEVEL UP! Значит нужно держать файл под блокировкой пока одна нить ходит за данными, но остальные будут ждать окончания блокировки...

LEVEL UP! Тогда пусть пока одна нить ходит за данными, а остальные нити возвращают старое значение, но что если возвращать нечего или та нить что пошла за данными упала...

LEVEL UP! Использовать спинлок (тут придётся угадывать сколько времени), пока не появится значение или пока не стало понятно что нить упала. Если нить упала, попытаться занять её место или вернуть старое.

Здесь не всё размышление, но суть сводится к тому, что кэш блокируется только на время чтения записи, несколько запросов не ходят за данными одновременно, но и не ждут пока их принесут.
Но это всё лирика, мне важно точно можно ли положить на flock, иначе вся задумка не реализуем.

З.Ы. Подобную стратегию можно использовать и с мемкэшем, но у меня его нет Улыбка
2. caballero - 28 Ноября, 2012 - 19:13:17 - перейти к сообщению
о базах данных слышал что нибудь?
3. EuGen - 28 Ноября, 2012 - 19:14:02 - перейти к сообщению
PHP:
скопировать код в буфер обмена
  1. $rFile = fopen("/tmp/lock.txt", "r+");
  2. if(flock($rFile, LOCK_EX))
  3. {
  4.     //read&write  NEW data
  5.     flock($rFile, LOCK_UN); //php 5.3+ could use fclose() to do the same
  6. }
  7. else
  8. {
  9.     //already locked, return OLD data
  10. }

?
На Win-системах flock вместо рекомендательной реализует обязательную блокировку. На *nix этого можно достичь, но соответствующая ФС должна быть смонтирована с опцией mand, а так же поддерживать системный вызов fcntl()
Если ФС не поддерживает обязательную блокировку, это значит, что блокировка файла не гарантируется и остается на усмотрение ресурса, пытающегося получить доступ к блокируемому файлу.
4. Самогонщик - 28 Ноября, 2012 - 19:20:40 - перейти к сообщению
caballero пишет:
о базах данных слышал что нибудь?

Конечно слышал, оракловая моя любимая. Но не будем об этом...
Делать на бд во-первых не интересно, а во вторых не хочется часто ходить за данными, которые обновляются редко, а показываются часто, очень часто.

EuGen пишет:
ФС должна быть смонтирована с опцией mand, а так же поддерживать системный вызов fcntl()

Вот это по делу. Тогда такой вопрос, допустим экспериментальным путём я могу выяснить поддерживается ли лок на моём шаред хостинге, но как можно это понять в рантайме?

EuGen пишет:
//already locked, return OLD data

Вот тут непонятно ожидает ли нить разлока или просто сразу в фальш и пошла дальше. Под виндой ожидает, это я проверил.
5. EuGen - 28 Ноября, 2012 - 19:24:45 - перейти к сообщению
Самогонщик пишет:
Под виндой ожидает, это я проверил.

EuGen пишет:
На Win-системах flock вместо рекомендательной реализует обязательную блокировку
6. Самогонщик - 28 Ноября, 2012 - 19:30:20 - перейти к сообщению
EuGen пишет:
На Win-системах flock вместо рекомендательной реализует обязательную блокировку
Для меня это звучит как: может реализуют блокировка, может нет, всем пофиг. Но ни как не "не вышло заблокировать, пофиг, идём дальше".

Я же не даром спрашиваю, было бы поведение этой функции везде однозначно, проблем бы не было, но документация какая-то не конкретная. Сейчас я пытаюсь понять, можно ли использовать её для моих целей. На всякий случай напомню: цель блокировать общий ресурс (файл) так, чтобы доступ к нему имела только одна нить в один момент времени, но в конечном итоге все желающие могли получить такой доступ (время работы с файлом очень мало).
(Добавление)
*ушёл просвещаться на тему рекомендательной блокировки в POSIX.
7. EuGen - 28 Ноября, 2012 - 19:33:15 - перейти к сообщению
Самогонщик пишет:
Но ни как не "не вышло заблокировать, пофиг, идём дальше".

Так а что это означает тогда. В примере выше - если не удалось заблокировать эксклюзивно, значит, блокировка уже есть - переходим к выдаче старого содержимого.
Если удалось - значит, ресурс свободен и можно его заблокировать - блокируем (в условии уже) - отдаем новый контент, снимаем блокировку. Что здесь "на месте стоять" должно? Исполнение скрипта что ли?
8. Самогонщик - 28 Ноября, 2012 - 19:42:35 - перейти к сообщению
EuGen пишет:
Так а что это означает тогда.
Быстрый гуглёж показал, что рекомендательная блокировка позволяет блокировать только на чтение или только на запись, и позволяет другим процессам на неё забивать. Ничего не попалось про повторное блокирование, жаль. В общем просто приму к сведению что flock ведёт себя по разному на винде и POSIX совместимых системах.

EuGen пишет:
блокировка уже есть - переходим к выдаче старого содержимого.
А вот тут сколько место, мне страшно возвращать старое содержимое, пока есть нить которая может в файл в момент чтения писать. И тут не понятно как быть.

EuGen пишет:
Что здесь "на месте стоять" должно? Исполнение скрипта что ли?
Да. Под виндой стоит, и такое поведение идеально подошло бы, но не всё так просто оказалось и потому мне надо понять как быть.
9. EuGen - 28 Ноября, 2012 - 19:44:23 - перейти к сообщению
Самогонщик пишет:
Быстрый гуглёж показал, что рекомендательная блокировка позволяет блокировать только на чтение или только на запись, и позволяет другим процессам на неё забивать.

EuGen пишет:
Если ФС не поддерживает обязательную блокировку, это значит, что блокировка файла не гарантируется и остается на усмотрение ресурса, пытающегося получить доступ к блокируемому файлу.

Самогонщик пишет:
И тут не понятно как быть.

Вариант эмуляции:
PHP:
скопировать код в буфер обмена
  1. while(!flock($rFile, LOCK_EX))
  2. {
  3.    usleep(100); //sleep for 0.1 sec (adjust this)
  4. }

?
10. caballero - 28 Ноября, 2012 - 19:46:38 - перейти к сообщению
SQLite
11. Самогонщик - 28 Ноября, 2012 - 20:00:58 - перейти к сообщению
EuGen пишет:
Вариант эмуляции
Спин лок, вариант вполне рабочий, но выглядит как костыль, потому как в то время как все успешные нити читают из файла, нить-неудачница постоянно натыкается на блокировку и падает по таймауту (300 раз не повезло, ага). Понятно, что такое бывает только при сииииильно высокой загрузке сервера, но всё равно не круто, ибо я не доверяю случайности.

По поводу цитирования. На всякий случай поясню в чём непонятка: я изначально знал, что на блокировку можно забивать, но вопрос был именно про различие в поведении функции на разных системах, если ресурс уже заблокирован. Ты тогда ответил цитатой с магическим "рекомендательная блокировка", и я решил, что из этого термина я как-то должен понять, почему на винде процесс ждёт, а никсах не ждёт. В общем с этим повторяться больше не надо. Подобьём итоги:
1. На винде блокирует всерьёз, повторная блокировка заставляет процесс ждать пока файл освободится.
2. В никсах на блокировку можно забивать, повторная блокировка возвращает фальш, решить проблему можно спин-локом.

Вопрос: есть ли решение получше спин-лока или это всё, финиш?

caballero пишет:
SQLite
Звучит заманчиво, но я ещё с файлами не закончил. И я достаточно упорот, чтобы задавать именно те вопросы на которые мне нужны ответы. Поэтому не нужно пытаться наставлять меня на путь истинный. В любом случае я хочу узнать как правильно работать из пхп с разделяемыми ресурсами в конкурентной среде на примере файла.
12. EuGen - 28 Ноября, 2012 - 20:06:37 - перейти к сообщению
Самогонщик пишет:
В никсах на блокировку можно забивать, повторная блокировка возвращает фальш, решить проблему можно спин-локом.

Опять могу привести цитирование:
EuGen пишет:
На *nix этого можно достичь, но соответствующая ФС должна быть смонтирована с опцией mand, а так же поддерживать системный вызов fcntl()

Самогонщик пишет:
нить-неудачница постоянно натыкается на блокировку и падает по таймауту (300 раз не повезло, ага)

- решаемо, например, так:
PHP:
скопировать код в буфер обмена
  1. $iSleep = 256;
  2. $iMin   = 2;
  3. while(!flock($rFile, LOCK_EX))
  4. {
  5.    usleep($iSleep);
  6.    $iSleep = max(array($iSleep/2, $iMin));
  7. }
13. Самогонщик - 28 Ноября, 2012 - 20:13:27 - перейти к сообщению
Т.е. только спин-лок? не круто, ну да ладно.

Я просто тогда не правильно понял твой ответ, что в цитировании и потому изменю вопрос, что у меня там: в рантайме я могу понять каким из двух способов работает flock ?

> max(array($iSleep/2, $iMin));
Забавная реализация (я бы с ифом написал), но вроде max без array можно.
14. EuGen - 28 Ноября, 2012 - 20:15:16 - перейти к сообщению
Самогонщик пишет:
в рантайме я могу понять каким из двух способов работает flock ?

Без root - доступа, увы, только попробовав установить блокировку (при инициализации приложения, например).
С root - доступом (маловероятно) - посмотрев опции монтирования через команду mount

По поводу массива - привычка обходиться без переменного числа аргументов там, где это возможно.
15. Самогонщик - 28 Ноября, 2012 - 20:19:26 - перейти к сообщению
EuGen, спасибо за консультацию, теперь уже можно серьёзно подумать на реализацией в свете открывшихся нюансов.
(Добавление)
Такс, нужно ещё немного конкретики. Операция копирования файла как работает?

Идеальный вариант: не даёт писать в тот файл что копируется и ждёт пока закроется все потоки/чтения записи того файла в который нужно записать и пока идёт запись не даёт для него открыть новых потоков.

 

Powered by ExBB FM 1.0 RC1