Python中的多线程:极高的CPU消耗
下面是一个简单的计时器代码,它每0.1秒在命令行中打印一个新的数字,同时也在等待你按下回车键。一旦你按下回车,计时器就会暂停,停止打印,并等待你再次按下回车,这样它就会继续计数和打印。
我遇到的问题是,当计时器处于“暂停”状态时,CPU的使用率几乎达到了100%(而在运行和打印的时候,使用率似乎不到1%)。
这是为什么呢?我哪里做错了?
以下是代码:
import time, thread, sys
time_passed = 0
l = []
trig = True
def input(l):
""" Waits for a keypress """
raw_input()
l.append(None)
def timer():
""" Prints out a number every millisecond """
global time_passed
time.sleep(.1)
time_passed += 1
sys.stdout.write(format(time_passed)+"\r")
sys.stdout.flush()
def running():
""" Toggles play/pause state if Enter is pressed """
global trig, l
while trig:
timer()
if l:
l = []
trig = False
return trig, l
def stopped():
""" Toggles pause/play state if Enter is pressed """
global trig, l
while not trig:
if l:
l = []
trig = True
return trig, l
def main():
""" Waits for a keypress while either running or stopping the timer """
global l, trig
while True:
thread.start_new_thread(input, (l,))
if trig: # The timer is running
running()
else: # The timer is stopped
stopped()
main()
谢谢。
1 个回答
1
好吧,如果它处于“停止”状态,你可以运行这个:
def stopped():
""" Toggles pause/play state if Enter is pressed """
global trig, l
while not trig:
if l:
l = []
trig = True
return trig, l
这个循环没有暂停或等待的部分。所以它会全速运行,不会回到系统。而在running
状态下,你确实调用了time.sleep
。在if
之前加上time.sleep(0.1)
,就能让它按照你想要的方式工作。
另外,个人建议一下,你可以稍微重构一下代码。两个功能相似的函数操作全局变量,会让人有点难以理解=)。
我会做成这样:
import time, thread, sys, threading
time_passed = 0
l = []
def input(l):
""" Waits for a keypress """
raw_input()
l.append(None)
def timer():
""" Prints out a number every millisecond """
global time_passed
time_passed += 1
sys.stdout.write(format(time_passed)+"\r")
sys.stdout.flush()
def running(state):
""" Toggles play/pause state if Enter is pressed """
global l
while True:
time.sleep(.1)
if state:
timer()
if l:
l = []
state = not state
return state
def main():
""" Waits for a keypress while either running or stopping the timer """
global l
state = True
while True:
thread.start_new_thread(input, (l,))
state = running(state)
main()
我还会考虑如何更好地发出切换的信号。我有点不喜欢从函数返回的想法,其实在运行时并不需要返回,只需切换状态就可以了。不过这只是个人喜好,我想。