Итак, apply_async
применяет процессы асинхронно - это означает, что все три запускаемых вами процесса запускаются одновременно и в некотором роде сражаются друг с другом.
Поскольку вы не запускаете эти процессы детерминистически, порядок их выполнения, вероятно, будет меняться при каждом запуске процесса.
Я предполагаю, что вы хотите:
- Очередь для заполнения ДО того, как процессы попытаются получить к ней доступ
- «Работа», которая будет равномерно распределена между процессами
Даже если вы не ограничите функции каким-либо образом, порядокони будут get()
предметов, все еще довольно случайно.Если вам действительно нужна функция 1, чтобы получать только шансы, и функция 2, чтобы получать только четности, и чтобы они были в строгом порядке, вам, вероятно, не нужна многопроцессорная обработка ...
import multiprocessing as mp
def fillQueue(lookup, q):
list(map(q.put, lookup))
print('Queue filled')
def printQueue(q, id):
while not q.empty():
print('Process {}: {}'.format(id, q.get()))
print('Process {}: Queue is empty!'.format(id))
if __name__ == "__main__":
pool = mp.Pool(processes=3)
manager = mp.Manager()
q = manager.Queue()
# no need to construct a list with a counter, we can just use the generator
lookup = range(101)
# do not fill the queue while processes are running, do it beforehand!
fillQueue(lookup, q)
# don't need different functions, since they are doing the same work
# just fire off multiple copies of the same function
p1 = pool.apply_async(printQueue, (q, 1,))
p2 = pool.apply_async(printQueue, (q, 2,))
pool.close()
pool.join()
Пример вывода:
Queue filled
Process 2: 0
Process 2: 1
Process 2: 2
Process 2: 3
Process 2: 4
Process 2: 5
Process 1: 6
Process 2: 7
Process 1: 8
Process 2: 9
Process 2: 10
Process 1: 11