Мне было интересно, есть ли разница между lua
os.execute('<command>')
и крутые
awful.spawn('<command>')
Я заметил, что предлагает использует os.execute
, для этого есть какая-то причина или это дело личного вкуса?
Никогда не используйте os.execute
или io.popen
. Они блокируют функции и вызывают очень плохую производительность и заметное увеличение ввода (мышь / клавиатура) и задержки перерисовки клиента. Использование этих функций является антипаттерном и только ухудшит ситуацию.
Смотрите предупреждение в документации https://awesomewm.org/apidoc/libraries/awful.spawn.html
Теперь, чтобы действительно ответить на вопрос, вы должны понимать, что Awesome однопоточный. Это означает, что он делает только одну вещь за раз. Если вы позвоните os.execute("sleep 10")
, ваша мышь будет продолжать двигаться, но в противном случае ваш компьютер зависнет на 10 секунд. Для команд, которые выполняются достаточно быстро, мая может пропустить это, но имейте в виду, что из-за правил задержки / частоты любая команда, выполнение которой занимает 33 миллисекунды, будет отбрасывать до 2 кадров в видеоигре со скоростью 60 кадров в секунду (и буду хотя бы одну). Если у вас много команд в секунду, они складываются и снижают производительность вашей системы.
Но Awesome не обречен на медлительность. У него может не быть нескольких потоков, но у него есть что-то, называемое сопрограммой, а также есть обратные вызовы. Это означает, что вещи, на выполнение которых требуется время, могут по-прежнему выполняться в фоновом режиме (с использованием потоков C или внешних процессов + сокетов). Когда они будут готовы, они смогут уведомить ветку Awesome. Это отлично работает и позволяет избежать блокировки Awesome.
Теперь мы переходим к следующей части. Если я сделаю:
-- Do **NOT** do this.
os.execute("sleep 1; echo foo > /tmp/foo.txt")
mylabel.text = io.popen("cat /tmp/foo.txt"):read("*all*")
На этикетке будет отображаться foo
. Но если я это сделаю:
-- Assumes /tmp/foo.txt does not exist
awful.spawn.with_shell("sleep 1; echo foo > /tmp/foo.txt")
mylabel.text = io.popen("cat /tmp/foo.txt"):read("*all*")
Тогда этикетка будет пустой. awful.spawn
и awful.spawn.with_shell
будут блокировать нет, и, таким образом, io.popen
будет выполняться до того, как sleep 1
завершится. Вот почему у нас есть асинхронные функции для выполнения команд оболочки. Есть много вариантов с отличными характеристиками и сложностью. awful.spawn.easy_async
является наиболее распространенным, поскольку он достаточно хорош для общего «я хочу выполнить команду и сделать что-то с выводом, когда он завершится».
awful.spawn.easy_async_with_shell("sleep 1; echo foo > /tmp/foo.txt", function()
awful.spawn.easy_async_with_shell("cat /tmp/foo.txt", function(out)
mylabel.text = out
end)
end)
В этом варианте Awesome не будет блокировать. Опять же, как и другие порождения, вы не можете добавить код вне функции обратного вызова, чтобы использовать результат команды. Код будет выполнен до завершения команды, поэтому результат еще не будет доступен.
Также существует так называемая сопрограмма, которая устраняет необходимость в обратных вызовах, но в настоящее время ее трудно использовать в Awesome, и ее также сложно объяснить.