Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python正在等待队列和事件_Python_Multithreading_Python 2.7_Multiprocessing - Fatal编程技术网

Python正在等待队列和事件

Python正在等待队列和事件,python,multithreading,python-2.7,multiprocessing,Python,Multithreading,Python 2.7,Multiprocessing,我有一个队列和一个事件。我希望在事件设置为True时退出循环,但是循环中有一个queue.get(),它会一直阻塞,直到其中有内容为止 设置closeEvent事件标志时,如何中止self.\u commandQueue.get()的等待 注意:我希望避免依赖于队列的阻塞性质,并希望根据队列的条件和eventflag进行阻塞 def _execute(self): while not self._closeEvent.isSet(): nextCommand = self

我有一个队列和一个事件。我希望在事件设置为True时退出循环,但是循环中有一个queue.get(),它会一直阻塞,直到其中有内容为止

设置closeEvent事件标志时,如何中止self.\u commandQueue.get()的等待

注意:我希望避免依赖于队列的阻塞性质,并希望根据队列的条件和eventflag进行阻塞

def _execute(self):
    while not self._closeEvent.isSet():
        nextCommand = self._commandQueue.get()
        self._commandExecutor.execute(nextCommand)
        self._commandQueue.task_done()

Queue.get
在没有参数的情况下调用时是一种阻塞方法

从文档:

将项目放入队列。如果可选args块为true且超时为 无(默认设置),如有必要,在空闲插槽可用之前阻止。 如果timeout为正数,则它最多会阻止超时秒数和秒数 如果该内存中没有可用的可用插槽,则引发完全异常 时间否则(block为false),如果有空闲项,则将该项放入队列 插槽立即可用,否则引发完全异常(超时 在这种情况下被忽略)

您需要这样做:

try:
    # If `False`, the program is not blocked, it will throw the Queue.Empty exception.
    my_data = queue.get(False)  
    .....Some Code......
except Queue.Empty:
    my_data = None # or whatever you want
更多选择

  • 立即行动

    Queue.get_nowait()

    这相当于
    get(False)

  • 使用超时

    my_data=queue.get(True,5)

    这将尝试获取5秒钟。如果获取失败(无法获取),它将引发相同的异常
    队列。为空


  • 队列
    根据 具体来说,它使用self.not_empty事件,您的应用程序也可以在尝试
    队列.get_nowait
    调用之前等待该事件


    至于等待几个事件,有些代码示例存在问题。

    您可能需要类似Windows
    WaitForMultipleObjects()
    的调用,但python事件和队列API没有提供这样的beast(但如果您严格使用Windows,则可以使用win32api来使用它),因此,如果您确实需要并行检查两个事件源,那么答案是“如果不进行轮询(或者通过猴子修补事件类来允许轮询),您就不能这样做”

    但如果您稍微灵活一点,您可以通过重新定义一点命令队列来安排类似的事情。如果命令队列是
    PriorityQueue
    ,则一旦事件发出信号,您可以使用正常优先级对正常作业进行排队,并使用额外的进程队列作为更高优先级的“停止”令牌

    STOP = None
    
    def _execute(self):
        while 1:
            nextCommand = self._commandQueue.get()[1]
            if nextCommand is STOP:
               break
            self._commandExecutor.execute(nextCommand)
            self._commandQueue.task_done()
    
    def wait_for_stop_signal(self):
        self._closeEvent.wait()
        self._commandQueue.put((-1, STOP))
    

    现在,您在自己的线程中运行
    wait\u for\u stop\u signal
    ,您就有了想要的行为(但是浪费一个线程而不是轮询,选择对您的用例更糟糕的方式)。

    我提供了以下两种选择,它们可能适合:

    解决方案1 在你的队列中放一个“神奇的退出标记”。我将不使用,如果需要,您可以使用特殊的退出消息。这与使用优先级队列方法大致相同,但(a)更简单,(b)但队列必须清空到标记点,这可能是您可以接受的,也可能是您不能接受的

    例如:

    # Untested
    # Processing thread
    def run(self):
        while True:
            msg = self.main_queue.get()
            if msg == None:
                break
            ...do..queue..work...
    
    def shutdown():
        self.main_queue.put(None)
    
    解决方案2 不要打电话给队列,直接走。创建一个事件对象,该对象在以下任一情况下发出信号: *队列里有东西。 *你想关机吗

    定义要添加到队列的方法,而不是将队列公开给外部世界:

    def add_to_queue(self, msg):
        self.main_queue.put(msg)
        self.my_event.set() # Signal the consumer
    
    def shutdown(self, msg):
        self.quit_event.set() # Set an event / condvar / msg to indicate exit
        self.my_event.set() # Signal something has happened.
    
    
    
    
    def run(self)
        while True:
            self.my_event.wait()
            if self.quit_event.is_set()
                break
            msg = self.main_queue.get(False) # Empty exception should not happen here
    

    您不一定需要退出事件,因为您可以假设一个空队列和一个有信号的my_事件意味着是时候退出了。尽管如此,我认为最好明确使用适当的指示符—消息、事件、条件变量等。

    是的,这正是我想要尝试和避免的。我不希望它仅基于队列而阻塞/不阻塞,并永远循环,我希望它阻塞,直到队列不为空且未设置closeEvent标志,然后在
    while
    条件下使用。这不会解决阻塞问题,它仍然会在while循环中循环。我希望它阻塞,直到队列中有东西并且未设置事件标志。我认为您的建议会使while循环迭代,但不会阻塞。还要注意while循环是一种while-True语句。是的,这就是我想要弄明白的。遗憾地发现python api中没有这样的东西:(您发布的帖子为schlenk所描述的内容提供了另一种选择。非常有用,谢谢:)可能不是等待信号的好风格,这是一个私有api细节,此外,在这种情况下也没有帮助。但是其他线程链接是有用的,尤其是(脏的,猴子补丁)版本,它只是重新定义了事件的作用。。。解决方案1是最佳的!!!