2016-08-09 1 views
1

J'ai deux versions de code qui suivent l'utilisation d'eventlet. L'attente est que les 2 appels spawn_n s'exécuteront simultanément, mais ce n'est pas le cas. L'exécution se passe en série.Le spawn Python Eventlet ne s'exécute pas simultanément

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, a commencé 140365670881088)>
09/08/2016 14: 04: 57,782866
abc bonjour !!
< _MainThread (MainThread, a commencé 140365670881088)>
09/08/2016 14: 05: 02,929903
xyz bonjour !!

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, a commencé 139897149990720)>
09/08/2016 14: 05: 25,613546
bonjour !! pqr
< _MainThread (MainThread, a commencé 139897149990720)>
09/08/2016 14: 05: 30,699473
LMN bonjour !!

Dans les deux versions du code, l'appel se produit de manière séquentielle.

+0

Après avoir ajouté un autre eventlet.spawn_n (bonjour, 'def') ou poll.spawn_n (bonjour, 'premier'). Les 2 derniers appels arrivent avec une différence de quelques millisecondes. A partir de la documentation, les eventlets ne sont pas des concurrents purs. Y a-t-il de toute façon une exécution simultanée réelle avec très peu de modifications? – nebi

+0

Définir 'concurrly' et en quoi est-il différent de' séquentiellement'. – temoto

Répondre

0
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)) 

Et vous verriez un résultat similaire à:

Turtle begin 
Achilles begin 
Turtle end 
Achilles end 
Total time: 0.10 

Ce qui montre que l'exécution des fonctions a été entrelacée à IO points d'attente (sommeil), qui est proche de la définition de coopérative concurrence. Notez également que le temps total n'est pas la somme de deux dortoirs, mais le maximum de surcharge de l'infrastructure (devrait être proche de zéro dans ce test de synthèse).

Le code en question ne pouvait pas afficher cela parce que vous n'aviez que des tirages (qui ne créent pas d'attente d'E/S dans Eventlet) avant l'E/S et aucun après. Donc ce que vous aviez fait exécuter est la suivante:

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