用于无限数据输入的python线程和队列(流)

时间:2010-07-06 10:05:35

标签: python multithreading queue multiprocessing

我想使用线程来处理流输入。

如何通过使用itertools.count

生成无限输入的以下代码

以下代码适用于: 'for i in itertools.count():'被替换为'for in in xrange(5):'

from threading import Thread
from Queue import Queue, Empty
import itertools

def do_work(q):
  while True:
    try:
        x = q.get(block=False)
        print (x)
    except Empty:
        break

if __name__ == "__main__":
  work_queue = Queue()
  for i in itertools.count():
    work_queue.put(i)

  threads = [Thread(target=do_work, args=(work_queue,)) for i in range(8)]

  for t in threads: t.start()
  for t in threads: t.join()

3 个答案:

答案 0 :(得分:2)

问题是itertools.count生成无限序列。这意味着for循环永远不会结束。你应该把它放在它自己的函数中并使它成为一个单独的线程。这样,当工作线程从队列中获取数据时,您将使队列增长。

答案 1 :(得分:1)

也许我错过了一些东西,但这不像在for循环之前创建和启动线程那么简单吗?

此外,当没有工作时让你的线程终止似乎是一个坏主意,因为将来可能会有更多的工作出现。当然,你希望它们阻止,直到有一些工作可用?

答案 2 :(得分:1)

您需要使用线程填充队列。您需要管理队列大小。特别是如果工人花时间处理物品。您需要标记完成的队列项。如果这与您关于推特和“极快”输入的其他问题有关,那么您在数据库插入方面还有很多事情要做。

对于相当复杂的主题,您的问题过于模糊。你似乎并不了解甚至你想要达到的目标,知道这并不容易。我建议您对自己要做的事情稍微具体一点。

以下是使用线程填充和使用队列的示例。队列大小未被管理。

from threading import Thread
from Queue import Queue, Empty, Full
import itertools
from time import sleep


def do_work(q,wkr):
  while True:
    try:
      x = q.get(block=True,timeout=10)
      q.task_done()
      print "Wkr %s: Consuming %s" % (wkr,x)
      sleep(0.01)
    except Empty:
      print "Wkr %s exiting, timeout/empty" % (wkr)
      break
    sleep(0.01)

def fill_queue(q,limit=1000):
  count = itertools.count()
  while True:
    n = count.next()
    try:
      q.put(n,block=True,timeout=10)
    except Full:
      print "Filler exiting, timeout/full"
      break
    if n >= limit:
      print "Filler exiting, reached limit - %s" % limit
      break
    sleep(0.01)

work_queue = Queue()

threads = [Thread(target=do_work, args=(work_queue,i)) for i in range(2)]
threads.insert(0,Thread(target=fill_queue,args=(work_queue,100)))

for t in threads:
  t.start()

for t in threads:
  t.join()

 Wkr 0: Consuming 0
 Wkr 1: Consuming 1
 Wkr 0: Consuming 2
 Wkr 1: Consuming 3
 ....
 Wkr 1: Consuming 99
 Filler exiting, reached limit - 100
 Wkr 0: Consuming 100
 Wkr 1 exiting, timeout/empty
 Wkr 0 exiting, timeout/empty