2

我目前正在使用 python (2.7) 编写一个有一些线程的 GUI。我遇到了一点,在获得一条信息之前我需要大约延迟一秒钟,但我不能让函数运行时间超过几毫秒。考虑到这一点,我正在尝试创建一个线程计时器,它将设置一个标志timer.doneFlag 并具有主要功能来继续戳看它是否完成。

这是工作。但并非总是如此。我遇到的问题是,有时我觉得 , 中的time.sleep函数run并没有完全等待一秒钟(有时甚至可能不会等待)。我所需要的只是我可以有一个标志,让我可以控制开始时间并在达到 1 秒时升起标志。

我可能做的太多只是为了得到一个线程化的延迟,如果你能提出一些建议,或者帮助我在下面的代码中找到一个错误,我将非常感激!

我附上了我使用的部分代码:

从主程序:

class dataCollection:
    def __init__(self):
        self.timer=Timer(5)
        self.isTimerStarted=0  
        return

    def StateFunction(self): #Try to finish the function within a few milliseconds

        if self.isTimerStarted==0:
           self.timer=Timer(1.0)
           self.timer.start()
           self.isTimerStarted=1

        if self.timer.doneFlag:
           self.timer.doneFlag=0
           self.isTimerStarted=0
           #and all the other code



import time
import threading
class Timer(threading.Thread):          
    def __init__(self, seconds):            
        self.runTime = seconds          
        self.doneFlag=0
        threading.Thread.__init__(self)
    def run(self):      
        time.sleep(self.runTime)    
        self.doneFlag=1
        print "Buzzzz"

x=dataCollection()
while 1:
    x.StateFunction()
    time.sleep(0.1)
4

1 回答 1

0

首先,您已经threading.Timer以较少的灵活性有效地进行了重建。所以我认为你最好使用现有的课程。(为每个计时器实例创建一个线程有一些明显的缺点。但如果你只想要一个一次性计时器,那很好。)

更重要的是,让你的主线程反复轮询doneFlag可能是个坏主意。这意味着您必须尽可能频繁地调用您的状态函数,无缘无故地烧毁 CPU。

大概你必须在几毫秒内返回的原因是你正在返回某种事件循环,大概是为了你的 GUI(但是,例如,网络反应器有同样的问题,有同样的解决方案,所以我会保持一般性)。

如果是这样,几乎所有此类事件循环都可以在事件循环中安排定时回调 - <code>Timer in wxcallLaterintwisted等。所以,使用它。

如果您使用的框架没有类似的东西,它希望至少有某种方式来发送事件/触发信号/发布消息/从外部调用它。(如果它是一个简单的基于文件描述符的反应器,它可能没有,但您可以通过将管道扔进反应器来自己添加它。)因此,更改您的Timer回调以发出事件循环的信号,而不是编写代码民意调查Timer

如果由于某种原因您确实需要轮询跨线程共享的变量,那么您确实应该使用Conditionor来保护它RLock。语言不能保证,当线程 0 更新值时,线程 1 会立即看到新值,甚至永远。如果您对(特定版本的)CPython 的内部有足够的了解,您通常可以证明 GIL 在特定情况下不需要锁。但除此之外,这是一场比赛。

最后:

我遇到的问题是,有时我觉得 run 中的 time.sleep 函数没有完全等待一秒钟(有时甚至可能不会等待)。

好吧,文档清楚地表明这可能发生:

实际的挂起时间可能少于请求的时间,因为任何捕获的信号都会在执行该信号的捕获例程后终止 sleep()。

因此,如果您需要保证它实际上至少休眠 1 秒,那么执行此操作的唯一方法是:

t0 = time.time()
dur = 1.0
while True:
    time.sleep(dur)
    t1 = time.time()
    dur = 1.0 - (t1 - t0)
    if dur <= 0:
        break
于 2013-03-20T21:04:42.937 回答