Последовательная очередь FIFO для командной строки linux
Я пытаюсь найти или реализовать простое решение, которое может последовательно ставить в очередь команды оболочки Linux, чтобы они выполнялись по одной за раз. Вот критерии:
- Очередь должна выполнять команды по одной за раз, то есть никакие две команды не могут выполняться одновременно.
- У меня нет списка команд раньше времени. Они будут приходить с веб-запросов, которые получает мой веб-сервер. Это означает, что очередь может быть пустой в течение длительного времени, и одновременно может поступить 10 запросов.
- Мой веб-сервер может выполнять только системные вызовы оболочки, поэтому эта программа / решение должно вызываться из командной строки.
- У меня только одна машина, поэтому она не может и не должна распределять работу между несколькими машинами.
Первоначально я думал, что at
Команда может делать то, что я хочу, но единственное, что она не выполняет команды последовательно.
Я думаю о реализации моего собственного решения в Python с этими частями:
- Иметь специальный каталог с файлом блокировки
- Команды в очереди хранятся в виде отдельных файлов с именем файла, содержащим увеличивающийся идентификатор последовательности или метку времени или что-то подобное, что я назову "командные файлы"
- Написать скрипт на Python, используя
fcntl
модуль в файле блокировки, чтобы убедиться, что запущен только 1 экземпляр скрипта - Скрипт будет следить за каталогом для любых файлов и выполнять команды оболочки в файлах в порядке имени файла
- Когда в каталоге больше нет "командных файлов", скрипт разблокирует файл блокировки и завершит работу.
- Когда мой веб-сервер хочет поставить в очередь задания, он добавит новый "командный файл" и вызовет мой скрипт на python
- Скрипт python проверит, запущен ли другой экземпляр. Если да, то завершите работу, что позволит другому экземпляру обрабатывать вновь помещенный в очередь "командный файл". Если нет, тогда заблокируйте файл блокировки и начните выполнять "командные файлы" в порядке
Похоже, это будет работать? Единственное условие гонки, с которым я не знаю, как справиться, - это когда первый экземпляр скрипта проверяет каталог и видит, что он пуст, и перед тем, как разблокировать файл блокировки, новая команда ставится в очередь и вызывается новый экземпляр скрипта., И этот новый скрипт завершится, когда увидит, что файл заблокирован. Затем оригинальный скрипт разблокирует файл и завершит работу.
Есть ли что-то, что уже делает это, поэтому мне не нужно реализовывать это самому?
2 ответа
Используйте именованную трубу, иначе FIFO:
mkfifo /tmp/shellpipe
Запустите процесс оболочки, чьи данные поступают из канала:
/bin/sh < /tmp/shellpipe
Когда веб-сервер хочет выполнить команду, он записывает ее в канал.
sprintf(cmdbuf, "echo '%s' > /tmp/shellpipe", command);
system(cmdbuf);
Очередь почтовых сообщений кажется специально созданной для этого и намного проще (и быстрее), чем возиться с файлами с метками времени и тому подобным. Скрипт может ставить запросы в очередь, когда они приходят; другой скрипт удаляет запросы и выполняет их. Существуют некоторые ограничения по размеру, которые применяются к очередям, но не похоже, что вы приблизитесь к их попаданию.