Python中的多线程:极高的CPU消耗

0 投票
1 回答
1827 浏览
提问于 2025-04-18 03:43

下面是一个简单的计时器代码,它每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()

我还会考虑如何更好地发出切换的信号。我有点不喜欢从函数返回的想法,其实在运行时并不需要返回,只需切换状态就可以了。不过这只是个人喜好,我想。

撰写回答