python - python 2.7中的线程延迟

标签 python multithreading timer delay flags

我目前正在使用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)

最佳答案

首先,您已经以较小的灵活性有效地重建了 threading.Timer 。因此,我认为您最好使用现有的类。 (为每个计时器实例创建一个线程有一些明显的弊端。但是,如果您只想要一个一次性计时器,那很好。)

更重要的是,让您的主线程反复轮询doneFlag可能不是一个好主意。这意味着您必须尽可能频繁地调用状态函数,没有充分的理由烧毁CPU。

大概您必须在几毫秒内返回的原因是,您正在返回某种事件循环,大概是针对您的GUI(但是,例如,网络 react 器具有相同的问题,采用相同的解决方案,所以我将保持一般性)。

如果是这样,几乎所有此类事件循环都可以在事件循环内安排定时回调-Timer中的wxcallLater中的twisted等等。因此,请使用它。

如果您使用的框架没有这样的框架,那么它至少希望可以通过某种方式发送事件/发出信号/发布消息/无论从外部调用什么。 (如果它是一个简单的基于文件描述符的 react 堆,它可能没有,但是您可以通过将管道扔进 react 堆来自己添加它。)因此,更改Timer回调以发出事件循环信号,而不是编写代码轮询Timer

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

最后:

The problem that I run into is that sometimes I feel like the time.sleep function in run , doesn't wait fully for a second (sometimes it may not even wait).



好吧,the documentation清楚地说这可能发生:

The actual suspension time may be less than that requested because any caught signal will terminate the sleep() following execution of that signal’s catching routine.



因此,如果您需要保证它实际休眠至少1秒钟,那么执行此操作的唯一方法是这样的:
t0 = time.time()
dur = 1.0
while True:
    time.sleep(dur)
    t1 = time.time()
    dur = 1.0 - (t1 - t0)
    if dur <= 0:
        break

关于python - python 2.7中的线程延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15532942/

相关文章:

python - Django 创建不正确的 MySQL LIKE 语句

python - 减少 ndarray 中的一维

java - AtomicInteger 与同步的 getter/setter

c# 事件处理程序被添加两次

c - 基于c中的计时器写入管道,阻塞问题

python - 有人可以说明 sklearn.mean_absolute_error 对于 2 个矩阵的基本方法吗?

python - UnitTest Python Mock 第一次调用方法,第二次调用照常进行

c - 如何在 C pthreads 中并行化线程

c++ - 处理线程失控问题的线程新手

Android 定时器 : postDelayed vs. 时间表