2016-04-01 16 views
0

yürütmek gevent.joinall Neden Aşağıdaki Python kodu vardır:piton tüm greenlets

Yukarıda görüldüğü gibi
>>> import gevent 
>>> from gevent import monkey; monkey.patch_all() 
>>> 
>>> def fooFn(k): 
...  return 'gevent_'+k 
... 
>>> threads = [] 
>>> threads.append(gevent.spawn(fooFn,'0')) 
>>> threads.append(gevent.spawn(fooFn,'1')) 
>>> 
>>> gevent.joinall([threads[1]]) 
>>> 
>>> print threads[1].value 
gevent_1 
>>> print threads[0].value 
gevent_0 
>>> 

, threads[0].valuefooFn gelen uygun bir değer var. Bu, threads[0] yeşili uygulamasının gerçekleştirildiği anlamına gelir.

Neden bu, yalnızca threads[1] yeşili gevent.joinall için geçtiğimde oldu?

Gerçekte yalnızca gevent.joinall'a iletilen yeşil parçacıkların gerçekleştirildiğinden nasıl emin olabilirim?

+0

'gevent.joinall()', yalnızca yeşil bantların bitmek üzere parametreler olarak geçirilmesini bekler ve ana iş parçacığıyla birleştirir. Bilgimden en iyi şekilde, diğer iş parçacıklarının herhangi birinin yürütülmesini engellemez - yeşil bantlar çalışmayı bitirinceye kadar ana parçacığı çıkarmamasını söyler. –

cevap

3

Yeşillikleriniz, greenlet.spawn() numaralı telefonu aradığınızda numaralı numaralı telefondan planlanmıştır. Başka bir deyişle, spawn()'u aradığınızda bir kerede oluşturulup başlatılır. Bu yüzden ilk yeşil alan bitti - yeşil çağlar onları ürettiğiniz andan itibaren yürüyordu ve siz Greenlet 1'in sonuçlarına bakmaya başladığınız zaman ikisi de idam edildi.

gevent.joinall() yeşil alanları yürütmez - yalnızca ana iş parçacığı (aslında spawn editörleri) çalışmayı bitirmek için parametre olarak iletilenleri beklemesini söyler. joinall numaralı telefonu arayarak, joinall()'daki yeşil noktaların sonuçlarına ulaşılmadan önce ana iş parçacığının sonlandırma ve çıkma riskini üstlenmez, sonra da sonuçlarının kim tarafından ele alınması gerekir?

  • Sen yerine bir komut dosyasından daha Konsol repl içinde joinall() seslendi:

    Burada, istediğiniz gibi gevents davranacağınızı görmemiz için değişmelidir iki şey yaptı. İşte

    , ana iş parçacığı - REPL - Eğer exit() arayabilir veya EOF işaret zaman REPL sadece biter çünkü greenlets dönmeden önce bitiremedi garantilidir olduğunu. Ancak, hiçbir kullanıcı etkileşimi olmayan bir komut dosyasında, bu lükse sahip değilsiniz - betikte hiçbir şey kalmayınca yürütme biter. Bu nedenle, ana iş parçacığının hiçbir zaman çıkmamasını ve yeşiliğinizin askıya alınmasını sağlamak için join() numaralı telefonu çağırıyoruz. konsolda joinall() arayarak hiçbir anlamı yoktur

    (bir garanti isterseniz sonraki greenlet bir işlevi çağırmak zaman greenlet sonuçlarını gerekecek rağmen, bu kadar iyi bir fikir)

  • gerekmezdi Eğer greenlet 2 değilken sadece greenlet 1 yürütüldüğünü garanti etmek istiyorsanız spawn()'u aradınız.Bunun yerine, read what the docs say:

    , yeni greenlet başlatmak hedef fonksiyonu ve Greenlet yapıcı onun argümanları geçmek ve başlangıç ​​çağrı() için:

    >>> g = Greenlet(myfunction, 'arg1', 'arg2', kwarg1=1)

    >>> g.start()

    veya classmethod kullanmak spawn(), aşağıdakileri yapan bir kısayol:

    şu anda yayınlanmaya başlaması gerekir greenlet belirtmek için start kullanma

iyi bir fikirdir. Yani: iki yeşil nesne oluşturunuz ve bunlardan sadece birinde bir tane yürütmek için sadece start'u arayın.