Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.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 我的HelloWorld队列是否正常工作?_Python_Multithreading_Queue - Fatal编程技术网

Python 我的HelloWorld队列是否正常工作?

Python 我的HelloWorld队列是否正常工作?,python,multithreading,queue,Python,Multithreading,Queue,我即将在一个应用程序中使用这个设计,但我对python中的线程和队列内容还相当陌生。很明显,实际的应用程序不是用来打招呼的,但设计是一样的——也就是说,有一个过程需要花费一些时间来设置和拆除,但我可以在一次点击中完成多个任务。任务将在随机时间到达,并且经常是突发的 这是一个合理且线程安全的设计吗 class HelloThing(object): def __init__(self): self.queue = self._create_worker() def _creat

我即将在一个应用程序中使用这个设计,但我对python中的线程和队列内容还相当陌生。很明显,实际的应用程序不是用来打招呼的,但设计是一样的——也就是说,有一个过程需要花费一些时间来设置和拆除,但我可以在一次点击中完成多个任务。任务将在随机时间到达,并且经常是突发的

这是一个合理且线程安全的设计吗

class HelloThing(object):

  def __init__(self):
    self.queue = self._create_worker()

  def _create_worker(self):
    import threading, Queue

    def worker():
      while True:
        things = [q.get()]
        while True:
          try:
            things.append(q.get_nowait())
          except Queue.Empty:
            break
        self._say_hello(things)
        [q.task_done() for task in xrange(len(things))]

    q = Queue.Queue()
    n_worker_threads = 1
    for i in xrange(n_worker_threads):
      t = threading.Thread(target=worker)
      t.daemon = True
      t.start()

    return q

  def _say_hello(self, greeting_list):
    import time, sys
    # setup stuff
    time.sleep(1)
    # do some things
    sys.stdout.write('hello {0}!\n'.format(', '.join(greeting_list)))
    # tear down stuff
    time.sleep(1)


if __name__ == '__main__':
  print 'enter __main__'

  import time
  hello = HelloThing()

  hello.queue.put('world')
  hello.queue.put('cruel world')
  hello.queue.put('stack overflow')

  time.sleep(2)

  hello.queue.put('a')
  hello.queue.put('b')

  time.sleep(2)

  for i in xrange(20):
    hello.queue.put(str(i))

  #hello.queue.join()

  print 'finish __main__'
  • 线程安全由队列实现处理(如果需要,还必须在_say_hello实现中处理)

  • 突发处理程序问题:突发应仅由单个线程处理。(例如:假设您的进程设置/拆卸需要10秒;在第1秒,所有线程将从第0秒开始忙于突发,在第5秒,所有线程将忙于处理新任务(或突发),但没有线程可用于处理它们/它)。因此,突发应该由特定时间窗口的最大任务数(或者可能是“无限”)来定义。队列中的条目应该是任务列表

  • 如何将突发任务列表分组? 我提供了一个解决方案作为代码,更容易解释

    producer_q = Queue()
    def _burst_thread():
       while True:
          available_tasks = [producer_q.get()]
          time.sleep(BURST_TIME_WINDOW)
          available_tasks.extend(producer_q.get() # I'm the single consumer, so will be at least qsize elements  
                                 for i in range(producer_q.qsize()))
          consumer_q.push(available_tasks)
    
    如果您希望在一次突发中最多包含消息,只需将可用的_任务分割到多个列表中即可

  • 线程安全由队列实现处理(如果需要,还必须在_say_hello实现中处理)

  • 突发处理程序问题:突发应仅由单个线程处理。(例如:假设您的进程设置/拆卸需要10秒;在第1秒,所有线程将从第0秒开始忙于突发,在第5秒,所有线程将忙于处理新任务(或突发),但没有线程可用于处理它们/它)。因此,突发应该由特定时间窗口的最大任务数(或者可能是“无限”)来定义。队列中的条目应该是任务列表

  • 如何将突发任务列表分组? 我提供了一个解决方案作为代码,更容易解释

    producer_q = Queue()
    def _burst_thread():
       while True:
          available_tasks = [producer_q.get()]
          time.sleep(BURST_TIME_WINDOW)
          available_tasks.extend(producer_q.get() # I'm the single consumer, so will be at least qsize elements  
                                 for i in range(producer_q.qsize()))
          consumer_q.push(available_tasks)
    

    如果您想在一次突发中拥有最多的消息,只需将可用的任务分片到多个列表中。

    您是说用
    extend
    代替
    expand
    ?另外,
    qsize
    的docstring表示它是近似值,不可靠,所以最好使用
    try:
    除了:
    on
    q.get_nowait()
    就像我原来的例子一样?@wim是的,extend是正确的方法。qsize()docstring中的“aproximative”表示不可靠(如果另一个并发线程获取或放置元素,则后续调用可能返回不同的结果);在我的示例中,并发线程只能放置新元素,因此get不会被阻止。您的建议也没问题,但有一个细微的区别(我的-在BURST\u TIME\u窗口过期后执行所有可用任务,您的-执行所有任务+在制作人变空之前将要执行的所有任务),您的意思是
    扩展
    而不是
    扩展
    ?另外,
    qsize
    的docstring表示它是近似值,不可靠,所以最好使用
    try:
    除了:
    on
    q.get_nowait()
    就像我原来的例子一样?@wim是的,extend是正确的方法。qsize()docstring中的“aproximative”表示不可靠(如果另一个并发线程获取或放置元素,则后续调用可能返回不同的结果);在我的示例中,并发线程只能放置新元素,因此get不会被阻止。你的建议也可以,但有一个细微的区别(我的-在BURST\u TIME\u窗口过期后执行所有可用任务,你的-执行所有任务+所有将要执行的任务,直到制作人变为空)