2015-08-21 26 views
7

varsayalım engellenmeyen fonksiyonu içine bir engelleme işlevini nasıl dönüştürüleceğini karıştı:Python Tornado - Uzun koşu fonksiyonu var

def long_running_function(): 
    result_future = Future() 
    result = 0 
    for i in xrange(500000): 
     result += i 
    result_future.set_result(result) 
    return result_future 

Yukarıdaki sonuçla kullanıcıyı yazdıran bir işleyici bir get fonksiyonu var For döngüsünün o xrange tüm numarasını ekler: Ben aynı anda iki web tarayıcılarda yukarıdaki kodu çalıştırırsanız

@gen.coroutine 
def get(self): 
    print "start" 

    self.future = long_running_function() 
    message = yield self.future 
    self.write(str(message)) 

    print "end" 

, alıyorum:

başlangıç ​​

başlangıç ​​engelleme gibi görünüyor

. Anladığım kadarıyla, @gen.coroutine ve yield bildirimi, get işlevindeki IOLoop'u engellemez, ancak, ko-rutinin içinde yer alan herhangi bir işlev varsa, IOLoop'u engeller.

Bu nedenle yaptığım diğer şey, long_running_function ürününü geri aramak ve yield gen.Task yerine kullanmaktır.

@gen.coroutine 
def get(self): 
    print "start" 

    self.future = self.long_running_function 
    message = yield gen.Task(self.future, None) 
    self.write(str(message)) 

    print "end" 

def long_running_function(self, arguments, callback): 
    result = 0 
    for i in xrange(50000000): 
     result += i 
    return callback(result) 

Bu da kesmiyor, beni veriyor:

başlangıç ​​

başlangıç ​​

ben bu yürütmek için konuları kullanabilirsiniz

Paralel, ama gitmek için yol gibi görünmüyor, çünkü çok fazla thre açıyor olabilir reklamlar ve Tornado'nun kullanım kılavuzuna göre, pahalı olabilir.

İnsanlar Tornado için async kütüphaneleri nasıl yazıyor?

cevap

6

Engelleme işlevi CPU'ya bağlıysa (for/xrange örneğiniz olduğu gibi), iş parçacığı (veya işlemler) engellemeyi yapmanın tek yoludur. Gelen istek başına bir iş parçacığı oluşturmak pahalıdır, ancak tüm CPU'ya bağlı işlemleri işlemek için küçük bir ThreadPoolExecutor yapma. bazı dış olaya bekliyor olmalı o uyandı böylece (örneğin ağın G/Ç gibi) ne zaman o olay:

konuları kullanmadan bir fonksiyon dışı engelleme yapmak için, fonksiyon olay güdümlü olmalıdır oluşur.

+0

Doğru olduğunu düşünüyorum, ama [Çağrı engelleme işlevleri] (htt p: //www.tornadoweb.org/en/stable/guide/coroutines.html#calling-blocking-functions) CPU'yu ya da olaya bağlı olduğundan bahsetme, sadece şöyle diyor: "En basit yol Bir koroutinden engelleme işlevi, Coroutines ile uyumlu Futures'ı döndüren bir ThreadPoolExecutor kullanmaktır. " –

0

Şu anda Tornado ve WebSocket işlevini kullanarak simulasyon programım için bir web arayüzü eklemeyi düşünüyorum. Simülasyon programım hesaplama açısından yoğun, yani, başka bir iş parçacığı veya işlem kullanılarak uygulanacak olan ben-darnell tarafından söylenen CPU'ya bağlı görevdir.

Şimdi benzer uygulama yapıyorum ve ne zaman bu cevabı güncellenecektir:

birçok araştırmalar sonra bu kaynaklar yardımcı olabilir düşünüyorum Daha fazla ilerleme var :)