2009-04-30 15 views
9

Satırlara self.output ve self.done True (veya maksimum yürütme süresine ulaşılana kadar) olan bir döngü ekleyen bir iş parçacığım var.Python - Threading ve bir süre True Loop

Bunu yapmanın daha etkin olup olmadığını görmek için sürekli denetleyen bir while döngüsünü kullanmaktan daha verimli bir yol var mı? çalışır durumdayken ise döngü CPU% 100'e başak neden olur ..

time.clock() 
while True: 

    if len(self.output): 
     yield self.output.pop(0) 

    elif self.done or 15 < time.clock(): 
     if 15 < time.clock(): 
      yield "Maximum Execution Time Exceeded %s seconds" % time.clock() 
     break 

cevap

11

Konularınız, ana göreviniz bunları tüketerek self.output'a ekleniyor mu? Eğer öyleyse, bu Queue.Queue için özel bir iş. Kişisel yapımcı ipler queue.put(item)

[Düzenle] Kuyruğa öğeler eklemek

import Queue 

# Initialise queue as: 
queue = Queue.Queue() 
Finished = object() # Unique marker the producer will put in the queue when finished 

# Consumer: 
try: 
    while True: 
     next_item = self.queue.get(timeout=15) 
     if next_item is Finished: break 
     yield next_item 

except Queue.Empty: 
    print "Timeout exceeded" 

self.done (örneğin birden çok öğe kontrol ederken orijinal kod bir yarış sorunu var: bir şey gibi Kodunuz haline gelmelidir bayrak ayarlanmadan önce sıraya eklenebilir ve kodun ilk seferde kurtarılmasına neden olabilir). Bir öneri ile güncellendi producer - Üretici iş parçacığı, tamamlandığını göstermek için sıraya özel bir belirteci (bitmiş) eklemelidir.

Not: Birden çok üretici iş parçacığınız varsa, bunların ne zaman tamamlandığını saptamak için daha genel bir yaklaşım gerekir.Bunu aynı strateji ile gerçekleştirebilirsiniz - her bir iş parçacığı Bitmiş bir işaretçi ve tüketici, sayı işaretlerini gördüğü zaman sona erer.

+0

OoOooo, şimdi konuşuyoruz. : D – Ian

+0

Bir iş parçacığının, iş parçacığı temiz bir şekilde çıkabilmesi için iş parçacığının bir şey yapmasını sağladıktan sonra, bir Queue.get() öğesinde engellemeyi engellemenin bir yolu var mı? – millimoose

+0

@Sii: Oluşturduğunuzda iş parçacığı daemonicini işaretleyebilirsiniz. Bu, programınız çıktığında iş parçacığının çıkacağı anlamına gelir. –

0

Kullanım time.sleep (saniye) cpu vazgeçmek iken her döngü tekrarında sonra kısa bir duraklama oluşturmak için. Her iterasyon sırasında uyuduğunuz zamanı, tamamlandıktan sonra işi hızlı bir şekilde yakalamanızın ne kadar önemli olduğuna bağlı olarak ayarlamanız gerekir.

Örnek:

time.clock() 
while True: 

    if len(self.output): 
     yield self.output.pop(0) 

    elif self.done or 15 < time.clock(): 
     if 15 < time.clock(): 
      yield "Maximum Execution Time Exceeded %s seconds" % time.clock() 
      break 

    time.sleep(0.01) # sleep for 10 milliseconds 
+0

uyku genellikle kötü performansla sonuçlanır. uyumayı kullanmadan önce senkronizasyonu düşünmelisiniz. – Francis

0

Burada ilkel bir senkronizasyon kullanmak zorunda. Bak burada: http://docs.python.org/library/threading.html.

Olay nesneleri çok basit görünüyor ve sorununuzu çözmelidir. Bir koşul nesnesi veya semafor da kullanabilirsiniz.

Bir örnek yayınlamıyorum çünkü hiç Etkinlik nesnesi kullanmadım ve alternatifler muhtemelen daha az basit.


Düzenleme: ben sorununuzu anladım gerçekten emin değilim. Bir iş parçacığı bazı durumlar bildirilene kadar bekleyebilirse, senkronizasyonu kullanın. Aksi halde, birisinin gönderdiği sleep() çözümü, çok fazla CPU zamanı almakla ilgili olacaktır. semaforu

0

kullanımı muteksin modül veya olay/

1

kullanın semaforu; İş parçacığı bittiğinde serbest bırakmalı ve işçinin semafor ile bitene kadar ekleme ipini engelleyiniz.

ie. İşçinin başında, işin başında self.done = threading.Semaphore() gibi bir şey yapın ve işiniz bittiğinde self.done.release(). Yukarıda belirttiğiniz kodda, yoğun döngü yerine, self.done.acquire(); İşçi iş parçacığı bittiğinde, kontrol geri dönecektir.

Düzenleme: Korkarım ki gerekli zaman aşımı değerine hitap etmiyorum; Bu issue standart kütüphanede bir semafor zaman aşımı gerekliliğini açıklar.