У меня есть сценарий командной строки, который выполняет вызов API и обновляет базу данных с результатами.
У меня есть ограничение в 5 вызовов API в секунду с поставщиком API. Выполнение сценария занимает более 0,2 секунды.
- Если я запускаю команду последовательно, она не будет работать достаточно быстро, и я буду делать только 1 или 2 вызова API в секунду.
- Если я запускаю команду последовательно, но одновременно с нескольких терминалов, я могу превысить ограничение в 5 вызовов / секунду.
Есть ли способ организовать потоки так, чтобы мой сценарий командной строки выполнялся почти ровно 5 раз в секунду?
Например, что-то, что будет работать с 5 или 10 потоками, и ни один поток не выполнит сценарий, если предыдущий поток выполнил его менее 200 мс назад.
command-line
multithreading
Вениамин
источник
источник
Ответы:
В системе GNU, и если у вас есть
pv
, вы можете сделать:-P20
Это выполнить не более 20$cmd
одновременно.-L10
ограничивает скорость до 10 байтов в секунду, поэтому 5 строк в секунду.Если у вас
$cmd
два медленных и приводит к достижению предела 20, тоxargs
чтение прекратится, пока$cmd
не вернется хотя бы один экземпляр.pv
будет продолжать запись в канал с той же скоростью, пока канал не заполнится (что в Linux с размером канала по умолчанию 64 КБ займет почти 2 часа).В этот момент
pv
перестану писать. Но даже тогда, когдаxargs
возобновит чтение,pv
попытается перехватить и отправить все строки, которые должны были быть отправлены ранее, как можно быстрее, чтобы поддерживать среднее значение 5 строк в секунду.Это означает, что до тех пор, пока это будет возможно с 20 процессами, удовлетворяющими этим 5 запускам в секунду в среднем требовании, он будет делать это. Однако при достижении предела скорость запуска новых процессов будет зависеть не от таймера pv, а от скорости, с которой возвращаются более ранние экземпляры cmd. Например, если 20 в данный момент работают и были в течение 10 секунд, и 10 из них решили завершить все одновременно, то 10 новых будут запущены одновременно.
Пример:
В среднем это будет 5 раз в секунду, даже если задержка между двумя запусками не всегда будет ровно 0,2 секунды.
С
ksh93
(или с,zsh
если вашаsleep
команда поддерживает доли секунды):Это не ограничивает число одновременных
your-command
s.источник
pv
команда, кажется, как раз то, что я искал, не мог надеяться на лучшее! Просто на этой линии:yes | pv -qL10 | xargs -n1 -P20 sh -c "$cmd" sh
не последний лиsh
излишний?sh
для$0
вашего$cmd
сценария. Это также используется в сообщениях об ошибках оболочкой. Без этого,$0
было быy
отyes
, так что вы получите сообщения об ошибках, какy: cannot execute cmd
... Вы могли бы также сделатьyes sh | pv -qL15 | xargs -n1 -P20 sh -c "$cmd"
sh
; и в моих тестах, когда я удаляю его, я не вижу никакой разницы!$cmd
используете$0
(почему бы это?) И для сообщений об ошибках. Попробуйте, например, сcmd=/
; без второгоsh
вы бы увидели что-то вродеy: 1: y: /: Permission denied
вместоsh: 1: sh: /: Permission denied
Проще говоря, если ваша команда длится менее 1 секунды, вы можете просто запустить 5 команд каждую секунду. Очевидно, это очень бурный.
Если ваша команда может занять более 1 секунды, и вы хотите распространить команды, вы можете попробовать
Кроме того, вы можете иметь 5 отдельных циклов, которые работают независимо, с минимумом 1 секунды.
источник
С программой на С,
Вы можете, например, использовать нить, которая спит в течение 0,2 секунды
используйте его, чтобы узнать, как создать поток: создайте поток (это ссылка, которую я использовал для вставки этого кода)
источник
cc
есть существующий инструмент Unix, и это не так много кода!Используя node.js, вы можете запустить один поток, который выполняет сценарий bash каждые 200 миллисекунд, независимо от того, сколько времени потребуется для ответа, поскольку ответ приходит через функцию обратного вызова .
Этот javascript запускается каждые 200 миллисекунд, и ответ получается через функцию обратного вызова
function (error, stdout, stderr)
.Таким образом, вы можете контролировать, что оно никогда не превышает 5 вызовов в секунду, независимо от того, насколько медленным или быстрым является выполнение команды или сколько времени он должен ждать ответа.
источник
Я
pv
какое-то время пользовался решением на основе Стефана Шазеля , но обнаружил, что оно выходило случайно (и молча) через некоторое время, от нескольких минут до нескольких часов. - Изменить. Причина была в том, что мой PHP-скрипт иногда умирал из-за превышения максимального времени выполнения, выход из него со статусом 255.Поэтому я решил написать простой инструмент командной строки, который делает именно то, что мне нужно.
Достижение моей первоначальной цели так же просто, как:
Он запускает почти ровно 5 команд в секунду, если не существует уже 20 одновременных процессов, и в этом случае он пропускает следующее выполнение, пока слот не станет доступным.
Этот инструмент не чувствителен к состоянию 255 выхода.
источник