EuGen, спасибо за консультацию, теперь уже можно серьёзно подумать на реализацией в свете открывшихся нюансов. (Добавление)
Такс, нужно ещё немного конкретики. Операция копирования файла как работает?
Идеальный вариант: не даёт писать в тот файл что копируется и ждёт пока закроется все потоки/чтения записи того файла в который нужно записать и пока идёт запись не даёт для него открыть новых потоков.
Я просто тогда не правильно понял твой ответ, что в цитировании и потому изменю вопрос, что у меня там: в рантайме я могу понять каким из двух способов работает flock ?
> max(array($iSleep/2, $iMin));
Забавная реализация (я бы с ифом написал), но вроде max без array можно.
Спин лок, вариант вполне рабочий, но выглядит как костыль, потому как в то время как все успешные нити читают из файла, нить-неудачница постоянно натыкается на блокировку и падает по таймауту (300 раз не повезло, ага). Понятно, что такое бывает только при сииииильно высокой загрузке сервера, но всё равно не круто, ибо я не доверяю случайности.
По поводу цитирования. На всякий случай поясню в чём непонятка: я изначально знал, что на блокировку можно забивать, но вопрос был именно про различие в поведении функции на разных системах, если ресурс уже заблокирован. Ты тогда ответил цитатой с магическим "рекомендательная блокировка", и я решил, что из этого термина я как-то должен понять, почему на винде процесс ждёт, а никсах не ждёт. В общем с этим повторяться больше не надо. Подобьём итоги:
1. На винде блокирует всерьёз, повторная блокировка заставляет процесс ждать пока файл освободится.
2. В никсах на блокировку можно забивать, повторная блокировка возвращает фальш, решить проблему можно спин-локом.
Вопрос: есть ли решение получше спин-лока или это всё, финиш?
caballero пишет:
SQLite
Звучит заманчиво, но я ещё с файлами не закончил. И я достаточно упорот, чтобы задавать именно те вопросы на которые мне нужны ответы. Поэтому не нужно пытаться наставлять меня на путь истинный. В любом случае я хочу узнать как правильно работать из пхп с разделяемыми ресурсами в конкурентной среде на примере файла.
Быстрый гуглёж показал, что рекомендательная блокировка позволяет блокировать только на чтение или только на запись, и позволяет другим процессам на неё забивать. Ничего не попалось про повторное блокирование, жаль. В общем просто приму к сведению что flock ведёт себя по разному на винде и POSIX совместимых системах.
EuGen пишет:
блокировка уже есть - переходим к выдаче старого содержимого.
А вот тут сколько место, мне страшно возвращать старое содержимое, пока есть нить которая может в файл в момент чтения писать. И тут не понятно как быть.
EuGen пишет:
Что здесь "на месте стоять" должно? Исполнение скрипта что ли?
Да. Под виндой стоит, и такое поведение идеально подошло бы, но не всё так просто оказалось и потому мне надо понять как быть.
На Win-системах flock вместо рекомендательной реализует обязательную блокировку
Для меня это звучит как: может реализуют блокировка, может нет, всем пофиг. Но ни как не "не вышло заблокировать, пофиг, идём дальше".
Я же не даром спрашиваю, было бы поведение этой функции везде однозначно, проблем бы не было, но документация какая-то не конкретная. Сейчас я пытаюсь понять, можно ли использовать её для моих целей. На всякий случай напомню: цель блокировать общий ресурс (файл) так, чтобы доступ к нему имела только одна нить в один момент времени, но в конечном итоге все желающие могли получить такой доступ (время работы с файлом очень мало). (Добавление)
*ушёл просвещаться на тему рекомендательной блокировки в POSIX.
Конечно слышал, оракловая моя любимая. Но не будем об этом...
Делать на бд во-первых не интересно, а во вторых не хочется часто ходить за данными, которые обновляются редко, а показываются часто, очень часто.
EuGen пишет:
ФС должна быть смонтирована с опцией mand, а так же поддерживать системный вызов fcntl()
Вот это по делу. Тогда такой вопрос, допустим экспериментальным путём я могу выяснить поддерживается ли лок на моём шаред хостинге, но как можно это понять в рантайме?
EuGen пишет:
//already locked, return OLD data
Вот тут непонятно ожидает ли нить разлока или просто сразу в фальш и пошла дальше. Под виндой ожидает, это я проверил.
Вопрос:
Насколько сильном можно надеяться на то, что функция flock работает как надо и что значит, если она вернула false? везде ли я могу надеяться на то, что доступ к заблокированному ресурсу будет последовательным?
Лирика:
Иногда мне хочется странного, вот в данных момент захотел написать модуль кэширования и конечно же не простой, а фильтипёрстовый. Для кэширования можно использовать разделяемый файл, но к нему одновременно могут обращаться несколько нитей...
LEVEL UP! Значит нужно делать блокирование файла на время чтения/записи, но если кэш протух, то несколько нитей могут полезь за одними и теми же данными в базу...
LEVEL UP! Значит нужно держать файл под блокировкой пока одна нить ходит за данными, но остальные будут ждать окончания блокировки...
LEVEL UP! Тогда пусть пока одна нить ходит за данными, а остальные нити возвращают старое значение, но что если возвращать нечего или та нить что пошла за данными упала...
LEVEL UP! Использовать спинлок (тут придётся угадывать сколько времени), пока не появится значение или пока не стало понятно что нить упала. Если нить упала, попытаться занять её место или вернуть старое.
Здесь не всё размышление, но суть сводится к тому, что кэш блокируется только на время чтения записи, несколько запросов не ходят за данными одновременно, но и не ждут пока их принесут.
Но это всё лирика, мне важно точно можно ли положить на flock, иначе вся задумка не реализуем.
З.Ы. Подобную стратегию можно использовать и с мемкэшем, но у меня его нет
В общем случилось тут странное... и мне понадобилось что-то для удалённой проверки домашних заданий. Само домашнее задание приходит в виде скана листа А4, на который очень хочется ставить отметки типа тех, что на безнес-линче у тёмы татьяныча. Т.е оставлять пометки прямо на изображении. Чем более готовое решение, тем лучше.
Если кто-нибудь видел что-то похожее, поделитесь ссылками и/или ключевыми словами.