Спаун Python Eventlet не выполняется одновременно
У меня есть следующие две версии кода с использованием eventlet. Ожидается, что 2 вызова spawn_n будут выполняться одновременно, но это не так. Казнь происходит поочередно.
import eventlet
import threading
import datetime
from eventlet.green import urllib2
def hello(name):
print eventlet.greenthread.getcurrent(), threading.current_thread()
print datetime.datetime.now()
print " %s hello !!" % name
urllib2.urlopen("http://www.google.com/intl/en_ALL/images/logo.gif").read()
eventlet.spawn(hello, 'abc')
eventlet.spawn(hello, 'xyz')
eventlet.sleep(0)
O / P: <_MainThread (MainThread, запущено 140365670881088)>
2016-08-09 14: 04: 57.782866
abc привет!!
<_MainThread (MainThread, запущен 140365670881088)>
2016-08-09 14: 05: 02.929903
xyz привет!!
import eventlet
import threading
import datetime
from eventlet.green import urllib2
def hello(name):
print eventlet.greenthread.getcurrent(), threading.current_thread()
print datetime.datetime.now()
print " %s hello !!" % name
urllib2.urlopen("http://www.google.com/intl/en_ALL/images/logo.gif").read()
pool = eventlet.GreenPool(size=4)
pool.spawn_n(hello, 'pqr')
pool.spawn_n(hello, 'lmn')
pool.waitall()
O / P: <_MainThread (MainThread, запущено 139897149990720)>
2016-08-09 14: 05: 25.613546
pqr привет!!
<_MainThread (MainThread, запущен 139897149990720)>
2016-08-09 14: 05: 30.699473
привет привет!!
В обеих версиях кода вызов происходит последовательно.
1 ответ
def fun(tag):
print('{0} begin'.format(tag))
eventlet.sleep(0.1) # pretty much the same as running HTTP request and throwing results away
print('{0} end'.format(tag))
t1 = time.time()
pool.spawn(fun, 'Turtle')
pool.spawn(fun, 'Achilles')
pool.waitall()
tt = time.time() - t1
print('Total time: {0:.2f}'.format(tt))
И вы увидите вывод, похожий на этот:
Turtle begin
Achilles begin
Turtle end
Achilles end
Total time: 0.10
Это показывает, что выполнение функций чередовалось в точках ожидания ввода-вывода (сна), что близко к определению кооперативного параллелизма. Также обратите внимание, что общее время - это не сумма двух снов, а максимум + затраты на инфраструктуру (в этом синтетическом тесте он должен быть практически нулевым).
Код, о котором идет речь, не мог показать это, потому что у вас были только распечатки (которые не создают IO-ожидание в Eventlet) до IO и ни один после. Итак, что вы на самом деле выполняли, так это:
main: pool.waitall() begin, switch to Eventlet loop
loop: oh, there are greenthreads scheduled to run now, switch to 1
1: print this
1: print that
1: urllib... start network IO, switch to loop
loop: there is another green thread scheduled, switch to 2
2: print this
2: print that
2: urllib... start network IO, switch to Eventlet loop
loop: wait for any event that should wake greenthread,
suppose that would be thread 1 urllib that is finished first
1: HTTP request finished, thread 1 finished, but no code to prove it
loop: wait for any event...
2: HTTP request finished, thread 2 finished
main: pool.waitall() finished