如果这很明显,请原谅我,但我无法从文档中判断使用队列时的输出是否排序。也就是说,如果输入是[1, 2, 3]
输出是f(1), f(2), f(3)
,还是会乱序?
编辑:我知道输入是在FIFO中处理的。但是FIFO检索是否一定能保证结果也按顺序返回?
不,它们将按照完成的顺序进入队列,而不是按启动顺序进入队列。这意味着,如果您以特定的顺序开始您的流程,它们可能会也可能不会按该顺序完成。如果顺序对您很重要,您应该将包含结果的起始顺序传回队列,也许作为元组queue.put((order, result))
。以下示例显示了您从队列中取出的随机顺序。(仍然是先进先出)
import multiprocessing
import random
import time
def square(x, queue):
# Sleep for a value between 0 and 1.
time.sleep(random.random())
queue.put(x**2)
queue = multiprocessing.Queue()
for i in range(10):
process = multiprocessing.Process(target = square, args = (i, queue))
process.start()
results = []
for i in range(10):
results.append(queue.get())
print (results)
这给了我[25, 16, 9, 0, 36, 64, 81, 1, 49, 4]。
假设你的任务相当简单,我总是更喜欢使用 Python 的Pool
功能及其相应的pool.map()
函数,它确实保证了根据输入顺序保留输出顺序。
我有一个情况,我必须将所有multiprocessing.Queue
替换为m = multiprocess.Manager()
m.Queue
,以便对所有队列进行排序。但是,我无法用一个简单的示例重现它。
我真的不知道为什么,但如果有人因为他们的队列出现故障而来到这里,我建议尝试一下。
队列
在 FIFO 队列中,添加的第一个任务是第一个检索到的任务
class Queue.Queue(maxsize=0) FIFO 队列的构造函数
是的,多处理队列是 FIFO(先进先出)。
多处理队列永远不会乱序。从文档中明确提到了 3 种类型。FIFO
、LIFO
和优先级队列(一种自定义顺序的方法)。默认顺序,即。class Queue.Queue
正在使用FIFO
在 FIFO 队列中,添加的第一个任务是第一个检索到的任务
所以考虑到这一点,是的,多处理队列保持顺序。
我发现多个进程使用的队列会得到一些非常意外的排序,即使 maxsize=1 您希望它以串行方式运行。官方文档支持我的实验:
如果多个进程正在对对象进行排队,则 要在另一端无序接收的对象。但是,对象 由同一进程排队将始终按预期顺序排列 互相尊重。
一旦访问它的进程数量增加,我在管理器队列上遇到了同样的问题。
从我的实验中,我发现管理此问题的最佳方法是使用JoinableQueue
,并在处理队列 get 的代码末尾手动调用task_done()
,尤其是在我的情况下,您正在处理两个队列进行输入和输出。 即JoinableQueue1.get()
- 处理数据 -JoinableQueue2.put()
- 然后time.sleep(0.1)
并JoinableQueue1.task_done()
.如果使用JoinableQueue.join()
方法,还可以更好地从许多进程使用的共享队列中获取 FIFO。