2010-02-11 20 views
9

İki konuları çalışan basit bir uygulama yazmak gerekir zamanlanmış dönemlerde ishal, diyelim ki her 1 dakikalık - iplik 2: sadece 'normal' iken 'şeyler'Bükümlü konular ... bunları nasıl kullanmalı? - Konu 1:

yapar Gerçek döngü

zamanlanmış aralıklarla çalıştırmak için değil gereklilik eğer ben hiç bükülmüş bakmadıysanız, ama basit uyku (60) yeteri kadar iyi değildir ve inşaat gibi olurdu:

l = task.LoopingCall(timed_thread) 
l.start(60.0) 
reactor.run() 

orada ne istediğini elde etmek için gerçekten basit görünüyordu .

Şimdi, başka bir iş parçacığı nasıl ekleyebilirim?

Burada iki seçenek göreceksiniz:

  • Kullanım parçacığı kütüphanesi ve benim ederken döngüye iki 'piton lifler' birini çalıştırın ve başka çalışan reactor.run(). Ancak Google bu yaklaşıma itiraz ediyor ve twisted threading
  • Twisted threading kullanılmasını önerir. Denediğim şey bu, ama bir şekilde bu bana biraz garip görünüyor.

    def timed_thread(): 
        print 'i will be called every 1 minute' 
        return 
    
    def normal_thread(): 
        print 'this is a normal thread' 
        time.sleep(30) 
        return 
    
    l = task.LoopingCall(timed_thread) 
    l.start(60.0) 
    reactor.callInThread(normal_thread) 
    reactor.run() 
    

    iş gibi görünüyor Yani, fakat:

Burada ile geldi işte! Uygulamayı durduramıyorum. Eğer^C'ye basarsam, hiçbir şey yapmazdım ('callInThread' olmadan sadece beklediğiniz gibi durur).^Z kabuğunu bombalar, ve eğer daha sonra '% 1' i öldürürsem, işlemi öldürür (kabuk rapor eder), fakat 'normal' iş parçacığı çalışmaya devam eder. öldürmek PID ondan kurtulmak olmaz ve tek tedavi -9 öldürür. Gerçekten garip.

So. Neyi yanlış yapıyorum? Bükülmüş iki ipi uygulamak için doğru bir yaklaşım mı? Benimle uğraşmamalı mıyım? Zamanlamalı çağrıları uygulamak için başka 'standart' alternatifler nelerdir? ('Standart' Ben, bunları kolayca yükleyebilirim veya yükleyebilirim, indirmek ve rastgele web sayfalarından bazı rasgele komut dosyaları kullanmak istemiyorum).

+0

Konuları çok dikkatli bir şekilde bükülmüş (ve genel olarak python) olarak kullanın. "Ana" nın ne yapıyor? Sıklıkla kullanılan bir kullanım durumu, protokol istemcisi/sunucusu olarak istekte bulunur veya istekte bulunur. Reaktör, bu istekleri ele alacaktır ve engellemenin engellenmediğini varsayarak, belirli bir zaman aralığında belirli bir işlevi çalıştırabileceklerdir. – MattH

+0

İş parçacığı ile ilgili tehlike, dikkatli değilseniz, bir iş parçacığı, başka bir iş parçacığı tarafından kullanıldığında, verileri tahmin edilemeyen davranışlara neden olacak şekilde değiştirebilir. – MattH

+0

tüm 'ana' amacı sadece bu iki iş parçacığı ateş etmektir (aslında örnekte görebildiğiniz gibi sadece 4 satır), her iki işlev biraz daha detaylıdır, ancak diğerini işlemek açısından olağandışı hiçbir şey onu denetlemez. ama bu gerçekten önemli değil). Bu iki iş parçacığı herhangi bir veri paylaşmıyor btw – rytis

cevap

2

ana nispeten engellenmeyen olduğunu varsayarsak: gerçekten burada konuları neden ihtiyacım açıklamak vermedi

import random 
from twisted.internet import task 

class MyProcess: 
    def __init__(self): 
    self.stats = [] 
    self.lp = None 
    def myloopingCall(self): 
    print "I have %s stats" % len(self.stats) 
    def myMainFunction(self,reactor): 
    self.stats.append(random.random()) 
    reactor.callLater(0,self.myMainFunction,reactor) 
    def start(self,reactor): 
    self.lp = task.LoopingCall(self.myloopingCall) 
    self.lp.start(2) 
    reactor.callLater(0,self.myMainFunction,reactor) 
    def stop(self): 
    if self.lp is not None: 
     self.lp.stop() 
    print "I'm done" 

if __name__ == '__main__': 
    myproc = MyProcess() 
    from twisted.internet import reactor 
    reactor.callWhenRunning(myproc.start,reactor) 
    reactor.addSystemEventTrigger('during','shutdown',myproc.stop) 
    reactor.callLater(10,reactor.stop) 
    reactor.run() 
 
$ python bleh.py 
I have 0 stats 
I have 33375 stats 
I have 66786 stats 
I have 100254 stats 
I have 133625 stats 
I'm done 
+0

Bu, iş parçacığı kullanmaz. – MattH

+0

Bu, python dizilerini kullanmıyor demektir. Hala twisted lib tarafından işlenmiş olduğundan şüpheleniyorum? – rytis

+1

Hayır, bu iş parçacığı dişlidir. Twisted sadece bunu anlatırsanız thread kullanır. Http://twistedmatrix.com/documents/current/core/howto/threading.html – MattH

5

. Eğer olsaydınız, neden 'un neden'a ihtiyaç duymadığını açıklayabiliyordum. ;)

Bu, bir şeylerin temel anlayışınızın doğru olduğunu onaylayabilirim. Yine de, temizleyebileceğim olası bir yanlış anlama, "python thread" ve "Twisted thread" kelimelerinin birbirinden farklı olduğu fikridir. Onlar değil. Python bir iş parçacığı kitaplığı sağlar. Twisted'in thread API'lerinin tümü Python'un threading kütüphanesi açısından uygulanmaktadır. Sadece API farklıdır.

Bildiğim kadarıyla kapatma giderse, iki seçeneğiniz vardır.

  • Python'un iş parçacığı API'lerini doğrudan yayınlamaya başla ve iş parçacığı bir artalan yap. Daemon iş parçacığı hala çalışıyorken işleminiz çıkabilir. Bu çözümle ilgili olası bir problem, Python'un bazı sürümlerinin, kapanma zamanında bir kilitlenmeye yol açacak şekilde daemon iş parçacıkları ile ilgili sorunlara sahip olmasıdır.
  • İş parçanızı Twisted's API'lerini veya stdlib iş parçacığı API'lerini kullanarak oluşturun, ayrıca reactor.addSystemEventTrigger('before', 'shutdown', f)'u kullanarak bir Twisted kapatma kancası ekleyin. Bu kancada, iş parçacığıyla iletişim kur ve kapatıldığını söyle. Örneğin, Twisted iş parçacığı ile iş parçacığınız arasındaki threading.Event paylaşımını yapabilir ve set kancasını kullanabilirsiniz. İş parçacığı, ayarlanmış olup olmadığını fark edip etmediğini kontrol etmek için periyodik olarak kontrol edebilir. Kilitlenmemesinin yanı sıra, bu daemon iş parçacıklarına göre başka bir avantaj sağlar - işlem çıkmadan önce iş parçanızda bazı temizleme veya sonlandırma kodlarını çalıştırmanıza izin verir.
+0

+1 Merhaba JP, yardım için teşekkürler. Bükümlü bir taraftarın görevi olduğumu sanmıyorum. – MattH

+0

np Matt. :) Bence cevabın, "bir dakikadan fazla sürebilir" olan gizemli vakalarla uğraşmak dışında oldukça iyi olduğunu düşünüyorum. Bu vakaların ne olduğunu bilseydik, çözümünüzü bunlarla başa çıkmak için uyarlamanın ve aslında iş parçacıklarının kullanımını ortadan kaldırmanın bir yolunu önerebiliriz. –

+0

açıklamasına Matt'in cevap yorumuna bakın. Açıklamak zor, başa çıkmak zorunda olduğum çeşitli durumlar var. Bunu bir örnek olarak ele alalım (gerçeğe oldukça yakındır): t1, 1mil takvimlerinden gelen kayıtları bile okur ve o dakika gerçekleşmesi beklenen olayları bir DB tablosuna koyar. bu kadar. t2 (t3,4, ...) tabloyu tarar ve ondan talimatlar uygular. O olayın tam olarak işlenmesi gereken bir req yoktur, sadece tam zamanında o sıraya girmesi gerekir. Yani t2 (3,4, ...) dünyadaki her zaman var, ama t1 kısıtlı. – rytis