тарелка в раковине выдается доступному мойщику, который моет ее и отдает су-
шильщику, который сушит ее и отдает человеку, убирающему ее в сторону. Этот
Конкуренция
305
процесс может быть синхронным (работники ждут, когда им дадут тарелку, а затем
ждут, когда освободится следующий в очереди работник) или асинхронным (по-
суда поступает от работников с разной скоростью). Если у вас есть достаточно
работников и они трудятся в одном темпе, задача будет выполнена гораздо быстрее.
Процессы
Очереди вы можете реализовать множеством способов. Для одного компьютера
модуль стандартной библиотеки multiprocessing (с которым вы можете познако-
миться в разделе «Программы и процессы» главы 10) содержит функцию Queue.
Симулируем процессы одного мойщика посуды и одного сушильщика (кто-то мо-
жет отложить посуду в сторону позже), а также промежуточную очередь dish_queue.
Назовите эту программу dishes.py:
import multiprocessing as mp
def washer(dishes, output):
for dish in dishes:
print('Washing', dish, 'dish')
output.put(dish)
def dryer(input):
while True:
dish = input.get()
print('Drying', dish, 'dish')
input.task_done()
dish_queue = mp.JoinableQueue()
dryer_proc = mp.Process(target=dryer, args=(dish_queue,))
dryer_proc.daemon = True
dryer_proc.start()
dishes = ['salad', 'bread', 'entree', 'dessert']
washer(dishes, dish_queue)
dish_queue.join()
Запустите новую программу:
$ python dishes.py
Washing salad dish
Washing bread dish
Washing entree dish
Washing dessert dish
Drying salad dish
Drying bread dish
Drying entree dish
Drying dessert dish
Эта очередь похожа на простой итератор, который создает набор тарелок. В дей-
ствительности здесь создаются отдельные процессы, общающиеся между собой.
Я использовал JoinableQueue и последний метод join(), чтобы дать знать мойщику,
306
Глава 11. Конкуренция и сети
что вся посуда была высушена. В модуле multiprocessing существуют очереди
и других типов, вы можете обратиться к документации, чтобы получить больше