Python定时器不工作

0 投票
3 回答
756 浏览
提问于 2025-04-16 06:31

我有以下代码:

        def countdown():
            def countdown1():
                print 'countdown1'
                def countdown2():
                    def countdown3():
                        takePic()
                    self.pic.set_markup("<span size='54000'>1</span>");
                    print 1
                    t3 = Timer(1.0, countdown3)
                    t3.start()
                self.pic.set_markup("<span size='54000'>2</span>");
                print 2
                t2 = Timer(1.0, countdown2)
                t2.start()
            self.pic.set_markup("<span size='54000'>3</span>");
            print 3
            t1 = Timer(1.0, countdown1)
            t1.start()

        countdown()

这段代码应该显示一个从3开始的倒计时。数字3会出现,但之后就没有任何反应了。有人能帮忙吗?

3 个回答

0

你确定没有其他命令在阻塞吗?比如说 set_markup?我这里有一个简单的例子可以正常运行:

>>> from threading import Timer
>>> def lvl1():
    def lvl2():
        print "evaling lvl2"
        def lvl3():
            print "evaling lvl3"
            print "TakePic()"
        print 1
        t3 = Timer(1.0, lvl3)
        t3.start()
    print 2
    t2 = Timer(2.0, lvl2)
    t2.start()

>>> lvl1()
2
>>> evaling lvl2
1
evaling lvl3
TakePic()
2

你的主线程可能在定时器触发之前就已经结束了。最简单粗暴的解决办法就是让主线程睡一段时间,直到所有定时器都能正常工作。更合理的选择是,在countdown3结束时发出一个信号,比如用信号量,然后在主线程中等待这个信号。

还有一种更优雅的解决方案,可以和更广泛的调度和异步框架结合使用,那就是通过生成器来反转控制流程:

def countdown():
    self.pic.set_markup("<span size='54000'>3</span>");
    print 3
    yield 1.0

    print 'countdown1'
    self.pic.set_markup("<span size='54000'>2</span>");
    print 2
    yield 1.0

    self.pic.set_markup("<span size='54000'>1</span>");
    print 1
    yield 1.0

    takePic()

for t in countdown():
    time.sleep(t)
1

为什么不在你启动定时器线程之后,直接用 .join() 来让其他代码等到定时器完成后再继续呢?

撰写回答