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

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Кэширование на файлах или загадочный flock

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Описание: Попытка сделать кэширование на файлах без гонок
Самогонщик
Отправлено: 28 Ноября, 2012 - 19:01:41
Post Id



Посетитель


Покинул форум
Сообщений всего: 495
Дата рег-ции: Окт. 2011  


Помог: 8 раз(а)




Вопрос:
Насколько сильном можно надеяться на то, что функция flock работает как надо и что значит, если она вернула false? везде ли я могу надеяться на то, что доступ к заблокированному ресурсу будет последовательным?

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

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

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

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

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

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

З.Ы. Подобную стратегию можно использовать и с мемкэшем, но у меня его нет Улыбка
 
 Top
caballero
Отправлено: 28 Ноября, 2012 - 19:13:17
Post Id


Активный участник


Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011  
Откуда: Харьков


Помог: 126 раз(а)




о базах данных слышал что нибудь?


-----
Бесплатная система складского учета с открытым кодом https://zippy[dot]com[dot]ua/zstore
 
 Top
EuGen Администратор
Отправлено: 28 Ноября, 2012 - 19:14:02
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




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()
Если ФС не поддерживает обязательную блокировку, это значит, что блокировка файла не гарантируется и остается на усмотрение ресурса, пытающегося получить доступ к блокируемому файлу.


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
Самогонщик
Отправлено: 28 Ноября, 2012 - 19:20:40
Post Id



Посетитель


Покинул форум
Сообщений всего: 495
Дата рег-ции: Окт. 2011  


Помог: 8 раз(а)




caballero пишет:
о базах данных слышал что нибудь?

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

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

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

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

Вот тут непонятно ожидает ли нить разлока или просто сразу в фальш и пошла дальше. Под виндой ожидает, это я проверил.
 
 Top
EuGen Администратор
Отправлено: 28 Ноября, 2012 - 19:24:45
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Самогонщик пишет:
Под виндой ожидает, это я проверил.

EuGen пишет:
На Win-системах flock вместо рекомендательной реализует обязательную блокировку


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
Самогонщик
Отправлено: 28 Ноября, 2012 - 19:30:20
Post Id



Посетитель


Покинул форум
Сообщений всего: 495
Дата рег-ции: Окт. 2011  


Помог: 8 раз(а)




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

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


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Самогонщик пишет:
Но ни как не "не вышло заблокировать, пофиг, идём дальше".

Так а что это означает тогда. В примере выше - если не удалось заблокировать эксклюзивно, значит, блокировка уже есть - переходим к выдаче старого содержимого.
Если удалось - значит, ресурс свободен и можно его заблокировать - блокируем (в условии уже) - отдаем новый контент, снимаем блокировку. Что здесь "на месте стоять" должно? Исполнение скрипта что ли?


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
Самогонщик
Отправлено: 28 Ноября, 2012 - 19:42:35
Post Id



Посетитель


Покинул форум
Сообщений всего: 495
Дата рег-ции: Окт. 2011  


Помог: 8 раз(а)




EuGen пишет:
Так а что это означает тогда.
Быстрый гуглёж показал, что рекомендательная блокировка позволяет блокировать только на чтение или только на запись, и позволяет другим процессам на неё забивать. Ничего не попалось про повторное блокирование, жаль. В общем просто приму к сведению что flock ведёт себя по разному на винде и POSIX совместимых системах.

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

EuGen пишет:
Что здесь "на месте стоять" должно? Исполнение скрипта что ли?
Да. Под виндой стоит, и такое поведение идеально подошло бы, но не всё так просто оказалось и потому мне надо понять как быть.
 
 Top
EuGen Администратор
Отправлено: 28 Ноября, 2012 - 19:44:23
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Самогонщик пишет:
Быстрый гуглёж показал, что рекомендательная блокировка позволяет блокировать только на чтение или только на запись, и позволяет другим процессам на неё забивать.

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

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

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

?


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
caballero
Отправлено: 28 Ноября, 2012 - 19:46:38
Post Id


Активный участник


Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011  
Откуда: Харьков


Помог: 126 раз(а)




SQLite


-----
Бесплатная система складского учета с открытым кодом https://zippy[dot]com[dot]ua/zstore
 
 Top
Самогонщик
Отправлено: 28 Ноября, 2012 - 20:00:58
Post Id



Посетитель


Покинул форум
Сообщений всего: 495
Дата рег-ции: Окт. 2011  


Помог: 8 раз(а)




EuGen пишет:
Вариант эмуляции
Спин лок, вариант вполне рабочий, но выглядит как костыль, потому как в то время как все успешные нити читают из файла, нить-неудачница постоянно натыкается на блокировку и падает по таймауту (300 раз не повезло, ага). Понятно, что такое бывает только при сииииильно высокой загрузке сервера, но всё равно не круто, ибо я не доверяю случайности.

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

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

caballero пишет:
SQLite
Звучит заманчиво, но я ещё с файлами не закончил. И я достаточно упорот, чтобы задавать именно те вопросы на которые мне нужны ответы. Поэтому не нужно пытаться наставлять меня на путь истинный. В любом случае я хочу узнать как правильно работать из пхп с разделяемыми ресурсами в конкурентной среде на примере файла.

(Отредактировано автором: 28 Ноября, 2012 - 20:06:09)

 
 Top
EuGen Администратор
Отправлено: 28 Ноября, 2012 - 20:06:37
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Самогонщик пишет:
В никсах на блокировку можно забивать, повторная блокировка возвращает фальш, решить проблему можно спин-локом.

Опять могу привести цитирование:
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. }


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
Самогонщик
Отправлено: 28 Ноября, 2012 - 20:13:27
Post Id



Посетитель


Покинул форум
Сообщений всего: 495
Дата рег-ции: Окт. 2011  


Помог: 8 раз(а)




Т.е. только спин-лок? не круто, ну да ладно.

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

> max(array($iSleep/2, $iMin));
Забавная реализация (я бы с ифом написал), но вроде max без array можно.

(Отредактировано автором: 28 Ноября, 2012 - 20:15:54)

 
 Top
EuGen Администратор
Отправлено: 28 Ноября, 2012 - 20:15:16
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Самогонщик пишет:
в рантайме я могу понять каким из двух способов работает flock ?

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

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


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
Самогонщик
Отправлено: 28 Ноября, 2012 - 20:19:26
Post Id



Посетитель


Покинул форум
Сообщений всего: 495
Дата рег-ции: Окт. 2011  


Помог: 8 раз(а)




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

Идеальный вариант: не даёт писать в тот файл что копируется и ждёт пока закроется все потоки/чтения записи того файла в который нужно записать и пока идёт запись не даёт для него открыть новых потоков.
 
 Top
Страниц (2): [1] 2 »
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Работа с файловой системой и файлами »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB