Comments 34
Статья расчитана на начинающих, которые впервые слышат буквосочетание FIFO применительно к Linux.Поправте пожалуйста — … применительно к bash.
Просто Linux != bash.
Конкретно для Linux эту задачу решает incron
Как мне посоветовал telomejtel, также может подойти просто inotify. Incron работает, как я понимаю, на нем.
В моем посте же написано самое простое рукотворное решение из подручных средств.
В моем посте же написано самое простое рукотворное решение из подручных средств.
спасибо за incron, не знал!
А что мешало создать один скрипт, в котором сделать обработку в цикле, используя тот же sleep?
А чем flock не угодил? Ощущение, что изобрели велосипед
С lock-файлом мне удобнее работать.
Ощущение, что почти любой скрипт является велосипедом.
Ощущение, что почти любой скрипт является велосипедом.
Жмем случайно на ребут во время выполнения скрипта… И лок файл висит вечно.
Здесь я согласен. В процессе поиска решения. Может, у Вас есть уже готовые строчки?
Можно попробовать не просто пустой лок, а, скажем, писать в него pid текущей задачи.
А при попытке входа — проверять наличие /proc/$pid.
Но на практике тут тоже возможны коллизии, покуда пиды заданий не бесконечны и реюзаются.
А при попытке входа — проверять наличие /proc/$pid.
Но на практике тут тоже возможны коллизии, покуда пиды заданий не бесконечны и реюзаются.
Думаю, flock действительно справиться с этой проблемой. Доберусь до машины — проверю.
> А при попытке входа — проверять наличие /proc/$pid.
Хотя в задаче не описаны требования, но так будет непереносимо, например, на фре proc может не быть, а в солярисе другой формат.
Есть интересный способ — послать сигнал 0 (ноль). Если процесс существует, то вернется тру.
Правда, требует прав на отправку сигнала процессу.
Хотя в задаче не описаны требования, но так будет непереносимо, например, на фре proc может не быть, а в солярисе другой формат.
Есть интересный способ — послать сигнал 0 (ноль). Если процесс существует, то вернется тру.
Правда, требует прав на отправку сигнала процессу.
Ну, тут в любом случае «серебряной пули» не получится. Всё будет затачиваться на конкретную платформу.
На практике «на данной конкретной платформе» получится просто и компактно. Для теоретиков :).
А как бывает при попытке охватить все случаи, можно увидеть, например, рассматривая код межпроцессного лока в apache (Хоть там и не sh, но смысл тот же).
На практике «на данной конкретной платформе» получится просто и компактно. Для теоретиков :).
А как бывает при попытке охватить все случаи, можно увидеть, например, рассматривая код межпроцессного лока в apache (Хоть там и не sh, но смысл тот же).
Тогда лучше посылать не ноль (его вернёт любой процесс), а сделать свой обработчик пользовательского сигнала, который вернёт заранее заданную магическую константу.
(при перезагрузке никто не гарантирует, что под заранее записанным пидом окажется именно свой процесс, а не какой-то иной. А такой handshake позволит его узнать)
(при перезагрузке никто не гарантирует, что под заранее записанным пидом окажется именно свой процесс, а не какой-то иной. А такой handshake позволит его узнать)
> Ну, тут в любом случае «серебряной пули» не получится.
Совсем в любом не получится, но работа с сигналами это POSIX, а значит работать будет почти везде. А вот наличие и формат /proc вам никто не гарантирует. Посыл был такой =)
> который вернёт заранее заданную магическую константу.
Я таки извиняюсь, каким образом вы кому-т вернете из обработчика сигнала какую-то константу?
Совсем в любом не получится, но работа с сигналами это POSIX, а значит работать будет почти везде. А вот наличие и формат /proc вам никто не гарантирует. Посыл был такой =)
> который вернёт заранее заданную магическую константу.
Я таки извиняюсь, каким образом вы кому-т вернете из обработчика сигнала какую-то константу?
Блин, ну что за буквоедство!
Переформулирую, раз вас расстраивает слово «вернуть»: «как-то просигналить». Поменять состояние какого-нибудь условного объекта, доступного обоим процессам (например, «тронуть» «магический файл» — но это уже лишние детали реализации).
К тому же это в любом случае некритичная часть (ну, просто изначальная ситуация, о чём вся речь, достаточно гипотетическая. Никто в здравом уме не выключает компьютер reset-ом. А если такое случается, то гораздо проще проинициализировать всю систему во время стартапа оси, чем устраивать параноидальную проверку всего и вся при каждом чихе. Впрочем, от требований зависит, конечно).
А «серебряная пуля» для всех систем всё равно не выйдет. Банальный раздел /home на каком-нибудь vfat — и всё, уже приплыли.
Переформулирую, раз вас расстраивает слово «вернуть»: «как-то просигналить». Поменять состояние какого-нибудь условного объекта, доступного обоим процессам (например, «тронуть» «магический файл» — но это уже лишние детали реализации).
К тому же это в любом случае некритичная часть (ну, просто изначальная ситуация, о чём вся речь, достаточно гипотетическая. Никто в здравом уме не выключает компьютер reset-ом. А если такое случается, то гораздо проще проинициализировать всю систему во время стартапа оси, чем устраивать параноидальную проверку всего и вся при каждом чихе. Впрочем, от требований зависит, конечно).
А «серебряная пуля» для всех систем всё равно не выйдет. Банальный раздел /home на каком-нибудь vfat — и всё, уже приплыли.
Не переживайте вы так, все будет хорошо )
Я просто ежедневно сталкиваюсь с работой процессов, использующих локи и такие проверки, в том или ином виде, и делюсь с вами тем, что видел и возможными решениями.
То, что вы считаете лишними деталями реализации, чаще всего и «стреляет» (дьявол в мелочах!). Например, тач файла после проверки существования пида уже не атомарная операция, и это уже проблема. А еще недавно было, кстати, пид файл создан, но место на диске кончилось и процесс не записал туда пид.
Конечно, все зависит от требований к надежности.
Пули нет, но есть решения лучше, и есть хуже.
Вообще, «делай хорошо, а плохо само получится» )
Я просто ежедневно сталкиваюсь с работой процессов, использующих локи и такие проверки, в том или ином виде, и делюсь с вами тем, что видел и возможными решениями.
То, что вы считаете лишними деталями реализации, чаще всего и «стреляет» (дьявол в мелочах!). Например, тач файла после проверки существования пида уже не атомарная операция, и это уже проблема. А еще недавно было, кстати, пид файл создан, но место на диске кончилось и процесс не записал туда пид.
Конечно, все зависит от требований к надежности.
Пули нет, но есть решения лучше, и есть хуже.
Вообще, «делай хорошо, а плохо само получится» )
flock -w 0 /tmp/.{jobs_medvoodoo или любое имя для идентификации}.lock {вызов скрипта} &
как то так, и у вас пока процесс не закончится новый не вызовется. *фигурные скобки здесь в качестве ограничителя поля, в скрипте они не нужны.Лок-файл нужно в
/tmp
делать чтобы не было таких проблем с перезагрузкой.А удаление лок-файла или прочий «функционал десктруктора» зачастую комфортнее оформлять в обработчик trap. На случай какого-нибудь несанкционированного поведения «задачи».
Да и при санкционированном тоже (один раз вставил обработку — и всё, она есть; к концу уже не забудешь)
Да и при санкционированном тоже (один раз вставил обработку — и всё, она есть; к концу уже не забудешь)
Заинтересовали две строки на Баше. Никогда ими не пользовался; такое ощущение что зря. Может пояснит кто?
FILES_LIST=( ... )
${FILES_LIST[@]}
FILES_LIST=( $(ls $HOME/jobs/Input) )
Здесь мы присваиваем переменной FILES_LIST как массиву содержимое папки. Получаем, что FILES_LIST — массив (обращение к которому идет так
${FILES_LIST[0]}, ${FILES_LIST[1]}, etc...
А про
${FILES_LIST[@]}
могу сказать, что это — просто весь массив как элемент. Если сделать
echo ${FILES_LIST[@]}
то выведется весь массив как объект. Я использую это в том контексте, что пускаю через весь массив цикл for.
Думаю, flock — вам подойдёт гораздо больше для флага, что кто-то уже работает. Не надо на баше писать свой flock — всё равно плохой получился. Да и очередь тоже не вижу чтобы очищалась. После ребута пойдёте заново все задания выполнять из файлика?
Лучше почитайте что такое очередь.
Во-первых к сожалению после ребута ничего не будет.
Во-вторых пайп на то и пайп, что если из него взяли что-то, его там уже не будет. Да и на диск ничего не пишется.
Во-первых к сожалению после ребута ничего не будет.
Во-вторых пайп на то и пайп, что если из него взяли что-то, его там уже не будет. Да и на диск ничего не пишется.
вот потому-то и возникает вопрос обоснованности решения с очередью.
Мне кажется проще было-бы так —
каталоги Input, Work, Done.
Скрипт смотрит каталог Work. Если там что-то есть, то запускает выполнение, а потом переносит файл в Done. Если нет, то перемещает туда один файл из Input. работу с лок-файлами добавить по вкусу.
Решение ничем не хуже, но при этом очередь переживает перезагрузку без проблем. Потому как очередью является сам каталог Input.
Мне кажется проще было-бы так —
каталоги Input, Work, Done.
Скрипт смотрит каталог Work. Если там что-то есть, то запускает выполнение, а потом переносит файл в Done. Если нет, то перемещает туда один файл из Input. работу с лок-файлами добавить по вкусу.
Решение ничем не хуже, но при этом очередь переживает перезагрузку без проблем. Потому как очередью является сам каталог Input.
Я бы еще сделал nohup перед строчкой с & в скрипте отправляющий задания
Sign up to leave a comment.
Очередь тяжелых заданий на bash