如何修复此脚本以便它不会挂起CPU?

时间:2012-08-16 15:22:42

标签: python performance keyboard cpu xlib

在我家的Kubuntu机器上,无论哪个窗口或应用程序具有焦点,我都会运行一个脚本在每个按键上发出蜂鸣声,改编自this insightful page

#!/usr/bin/env python 

from Xlib.display import Display
import os
import sys

ZERO=[]
for i in range(0,32):
        ZERO.append(0)
ignorelist=[ZERO]

def main():    
        if os.getuid()==0:
                os.system("modprobe pcspkr")
                print("Speaker enabled, start as normal user")
                sys.exit()

        print("If no beep is heard, then run as root to enable pcspkr")

        disp = Display()
        while 1:
                keymap=disp.query_keymap()
                if keymap not in ignorelist:
                        os.system("beep")

if __name__ == '__main__':
        main()

这个脚本运行得很好,但它将我的双核Intel机器的两个CPU都固定在每个80%左右,所以我对这台机器几乎无能为力。如何在不干扰其操作的情况下降低此简单脚本的CPU要求?换句话说,无论窗口或应用程序有什么焦点,它都应该在按键时发出哔哔声。

如果在Python中无法做到这一点,我应该关注哪些其他技术? C?我会假设有一些内核组件通知应用程序的按键:KDE如何处理全局快捷方式?我怎样才能让我的申请也收到这些通知?

我的目标是在按下每个按键时发出哔哔声,因为我正在训练我的手指在机械键盘上打字而不会在没有丢失按键的情况下触底。我刚从Cherry Browns毕业到Cherry Blues,缺乏战术反馈需要一些时间来适应。

请注意,无论哪个窗口具有焦点,任何解决方案都必须发出蜂鸣声。此程序旨在用作将在我使用的所有应用程序的后台运行的守护程序。

感谢。

4 个答案:

答案 0 :(得分:12)

使用事件:

import Xlib
from Xlib.display import Display

display = Display()

screen = display.screen()
w = screen.root.create_window(0, 0, 100, 100, 1,
              screen.root_depth,
              event_mask = Xlib.X.KeyPressMask)
w.map()

while True:
    event = display.next_event()
    if event.type != Xlib.X.KeyPress:
        continue
    print "OHAI"

来自http://python-xlib.sourceforge.net/doc/html/python-xlib_10.html#SEC9

的详细信息

答案 1 :(得分:8)

你的while循环消耗了所有CPU的周期,因为它的执行速度尽可能快。你可以添加一个小的sleep()延迟,但你可能会错过一些关键事件。或者,考虑使用pyhook模块来监控按键操作。

答案 2 :(得分:5)

你的程序正在占用CPU,因为它正在运行一个无限循环,这会让你的CPU忙于每毫秒左右检查键盘状态,即使没有按下任何键。由于您的计算机没有迹象表明它可以停止,因此它将尽可能频繁地进行检查,从而消耗资源。

正如Iain所说,这个问题最优雅的解决方案是使用Display.next_event(),它将告诉程序等到收到新事件(例如按键)。在这段等待时间内,你的程序不会消耗大量的CPU,你的负载也会大幅下降。

答案 3 :(得分:5)

您可以使用nice启动脚本。 nice命令会降低脚本的优先级,因此它只会在系统没有其他任何操作时运行。这样它仍会占用CPU周期,但您可以正常使用系统执行其他任务。

有关详细信息,请参见手册页。

修改

要减少CPU使用率,可以使用time.sleep(0.01)添加一个小延迟。这将减少CPU负载,但会略微增加按键和产生的蜂鸣声之间的时间。