Ваша реакция на урок, кажется, показывает, что вы пропустили часть того, что он пытается показать.
В асинхронной части кода урока основная причина, по которой задачи завершаются в случайном порядкепотому что они спали в течение случайного периода времени .
Они все еще спят в течение произвольного периода времени в синхронной части кода, но потому чтокаждая задача выполняется после того, как предыдущая закончилась, они также заканчиваются в этом последовательном порядке.
Разница между вашим кодом и кодом асинхронного учебного пособия состоит в том, что вы спите в течение заданного периода времени, и поэтому ваши задачиследует завершить это количество времени позже, также в заранее определенном порядке.
Наконец, если вы соблюдаете наблюдательность, вы заметите, что они заканчивают в обратном порядке, как вы могли бы ожидать.
Почему это так?
Поскольку вы вставили блокирующий код в ваш пример.Код блокировки time.sleep()
.Когда что-то блокируется, это означает, что оно перехватило все выполнение для себя и больше не будет запускать ничего (например, другие ваши гринлеты) до тех пор, пока оно не завершится.
Так как это единственная «работа», котораякаждая функция делает ваш код снова синхронным.
При написании программ такого рода вы хотите, чтобы блокирующий код был как можно более несуществующим.Вы должны постоянно помнить о возможном блокировании кода, и обычно вы хотите найти неблокирующие альтернативы как можно чаще.
Gevent предоставляет неблокирующую версию time.sleep()
- gevent.sleep()
.Вы заметите, что это то, что используется в учебном коде.Вы также можете патч обезьяны эту функцию.На данный момент вы обычно предпочитаете просто использовать версию Gevent.
Просмотр списка вещей, которые исправляет monkey_patch
, должен дать вам хороший, но не исчерпывающий обзор типов обычных вещей.которые обычно блокируют.
edit: у вас также есть неверная логика в цикле создания задания.
лучше -
jobs = []
for i in x:
jobs.append(gevent.spawn(mytime, i))
или, проще, просто:
jobs = [gevent.spawn(mytime, i) for i in x]