我的HelloWorld队列是否有效?

时间:2011-08-24 02:25:24

标签: python multithreading queue

我即将在设计应用程序中使用此设计,但我对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__'

1 个答案:

答案 0 :(得分:0)

  1. 线程安全性由Queue实现处理(如果需要,您还必须在_say_hello实现中处理)。

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

  3. 如何组合突发任务列表? 我提供了一个代码解决方案,更容易解释......

    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)
    

    如果您希望突发中包含最多的消息,则只需将多个列表中的available_tasks切片。