很棒的 WM - os.execute 对比 afwul.spawn
Awesome WM - os.execute vs afwul.spawn
我想知道 lua 和
之间是否有任何区别
os.execute('<command>')
很棒的
awful.spawn('<command>')
我注意到 lain suggests 使用 os.execute
,有什么原因吗,还是个人品味问题?
永远不要使用 os.execute
或 io.popen
。它们是阻塞函数,导致性能非常差,输入 (mouse/keyboard) 和客户端重绘延迟显着增加。使用这些函数是一种反模式,只会让一切变得更糟。
查看文档中的警告https://awesomewm.org/apidoc/libraries/awful.spawn.html
现在要真正回答这个问题,您必须了解 Awesome 是单线程的。这意味着它一次只做一件事情。如果您调用 os.execute("sleep 10")
,您的鼠标将继续移动,但您的计算机将冻结 10 秒。对于执行速度足够快的命令,它 可能 可能会错过这个,但请记住,由于 latency/frequency 规则,任何需要 33 毫秒执行的命令都会被丢弃在 60fps 视频游戏中最多 2 帧(并且 将 至少丢掉一帧)。如果您每秒有很多命令,它们加起来会破坏您的系统性能。
但 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
完成之前执行 wayyy。这就是为什么我们有异步函数来执行 shell 命令。有许多具有不同特征和复杂性的变体。 awful.spawn.easy_async
是最常见的,因为它足以满足一般 "I want to execute a command and do something with the output when it finishes".
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 不会阻塞。同样,与其他 spawn 一样,您不能在回调函数之外添加代码来使用命令的结果。代码将在命令完成之前执行,因此结果尚不可用。
还有一种叫做协程的东西不需要回调,但目前很难在 Awesome 中使用,而且解释起来也很混乱。
我想知道 lua 和
之间是否有任何区别os.execute('<command>')
很棒的
awful.spawn('<command>')
我注意到 lain suggests 使用 os.execute
,有什么原因吗,还是个人品味问题?
永远不要使用 os.execute
或 io.popen
。它们是阻塞函数,导致性能非常差,输入 (mouse/keyboard) 和客户端重绘延迟显着增加。使用这些函数是一种反模式,只会让一切变得更糟。
查看文档中的警告https://awesomewm.org/apidoc/libraries/awful.spawn.html
现在要真正回答这个问题,您必须了解 Awesome 是单线程的。这意味着它一次只做一件事情。如果您调用 os.execute("sleep 10")
,您的鼠标将继续移动,但您的计算机将冻结 10 秒。对于执行速度足够快的命令,它 可能 可能会错过这个,但请记住,由于 latency/frequency 规则,任何需要 33 毫秒执行的命令都会被丢弃在 60fps 视频游戏中最多 2 帧(并且 将 至少丢掉一帧)。如果您每秒有很多命令,它们加起来会破坏您的系统性能。
但 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
完成之前执行 wayyy。这就是为什么我们有异步函数来执行 shell 命令。有许多具有不同特征和复杂性的变体。 awful.spawn.easy_async
是最常见的,因为它足以满足一般 "I want to execute a command and do something with the output when it finishes".
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 不会阻塞。同样,与其他 spawn 一样,您不能在回调函数之外添加代码来使用命令的结果。代码将在命令完成之前执行,因此结果尚不可用。
还有一种叫做协程的东西不需要回调,但目前很难在 Awesome 中使用,而且解释起来也很混乱。