python多处理问题

python多处理问题,python,process,queue,multiprocessing,Python,Process,Queue,Multiprocessing,我在使用进程和队列时遇到了一些问题 当我运行以下代码时,目标函数只是从主队列中获取一个项,并将其添加到该进程特定的另一个队列中 import sys import multiprocessing from Queue import Empty # This is just taking a number from the queue # and adding it to another queue def my_callable(from_queue, to_queue): while

我在使用进程和队列时遇到了一些问题

当我运行以下代码时,目标函数只是从主队列中获取一个项,并将其添加到该进程特定的另一个队列中

import sys
import multiprocessing
from Queue import Empty

# This is just taking a number from the queue
# and adding it to another queue
def my_callable(from_queue, to_queue):
    while True:
        try:
            tmp = from_queue.get(0)
            to_queue.put(tmp)
            print to_queue
        except Empty:
            break

# Create a master queue and fill it with numbers
main_queue = multiprocessing.Queue()
for i in xrange(100):
    main_queue.put(i)

all_queues = []
processes = []
# Create processes
for i in xrange(5):
    # Each process gets a queue that it will put numbers into
    queue = multiprocessing.Queue()
    # Keep up with the queue we are creating so we can get it later
    all_queues.append(queue)
    # Pass in our master queue and the queue we are transferring data to
    process = multiprocessing.Process(target=my_callable,
                                      args=(main_queue, queue))
    # Keep up with the processes
    processes.append(process)

for thread in processes:
    thread.start()

for thread in processes:
    thread.join()
当目标函数打印正在使用的队列时,您会注意到一个队列几乎被独占使用

然后,如果您获取输出并打印它,您将看到大多数数字最终位于单个队列下

def queue_get_all(q):
   items = []
   maxItemsToRetreive = 100
   for numOfItemsRetrieved in range(0, maxItemsToRetreive):
       try:
           if numOfItemsRetrieved == maxItemsToRetreive:
               break
           items.append(q.get_nowait())
       except Empty, e:
           break
   return items

for tmp in all_queues:
    print queue_get_all(tmp)
这是什么原因造成的?在我的代码中是否有一些我应该做的事情可以平衡这些进程正在做的工作

输出

[0, 2, 3, 4, 5, 6, 7, 8]
[1, 9, 10]
[11, 14, 15, 16]
[12, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
[13]

我认为你有两个问题:

def my_callable(from_queue, to_queue):
    while True:
        try:
            tmp = from_queue.get(0)
            to_queue.put(tmp)
            print to_queue
        except Empty:
            break
从以下文件:

从队列中删除并返回项目。如果可选args block为True(默认值)且timeout为None(默认值),则在项目可用之前,如有必要,请进行阻止。如果timeout为正数,则它最多会阻止超时秒并引发队列。如果在此时间内没有可用项,则为空异常。否则(block为False),如果立即可用,则返回一个项目,否则引发队列。空异常(在这种情况下忽略超时)

由于您将
0
作为第一个参数传递,因此它相当于
get(False)
。这使得它是非阻塞的,这意味着如果它不能立即获得一个值,它将引发一个空异常,这将结束您的工作进程。由于您所有的“work”函数都是相同的,并且试图同时从主队列中提取,因此有些函数可能无法立即获取值,并将死亡

.get()
一个小的超时应该可以解决这个问题

第二个问题是,您的“工作”功能基本上不需要花费任何时间来完成。使用
sleep(.2)
稍微暂停一下,以模拟一些非繁琐的工作,它将分布在所有工作人员中:

def my_callable(from_queue, to_queue):
    while True:
        try:
            tmp = from_queue.get(True, .1)
            sleep(0.2)
            to_queue.put(tmp)
        except Empty:
            break
编辑:


我忘了说,通常这类问题最好不要依赖
.get()
的超时来通知队列结束。如果使用某种类型的“队列结束”标记对象传递到队列中,告诉工作人员该退出了,则可以获得更多的控制。通过这种方式,您可以让它们全部阻塞,等待新的输入或退出“命令”。

Ok。因此,这确实平衡了工作。因此,将超时设置为1,睡眠设置为.01——那么知道最后应该是什么类型的对象吗?也许是一个特定的字符串?