2009-02-09 17 views
25

Uygulamaya teslim edilmek istenen kuyruk iletilerini beklemek ve yanıtlamak için iş parçacıkları kullanan bir kuyruk işleme uygulaması yazıyorum. Uygulamanın ana kısmı için sadece aktif kalması gerekiyor. gibi bir kod Örneğin:Python: Uzun koşu süreçleri için Geç mi Uyu?

 
while True: 
    pass 

veya

 
while True: 
    time.sleep(1) 

biri bir sistemde en az etkisi olacak Hangi? Hiçbir şey yapmanın tercih edilen yolu nedir, ancak bir python uygulaması çalışıyor mu?

+6

doğru cevap yoklama yapmak değil G/Ç hiç Örneğin, OS'nin okumaya hazır bir şey olana kadar uyuduğu select() çağrısına bakın. –

+0

İş parçacıkları durumunda, iletileri bekleyen TCP bağlantılarını engelliyorlar. Benim sadece endişe duyduğum ana iş parçacığı ve komut satırı seçeneklerini işlemek, yapılandırma ve iş parçacığı tekme işlemek bir şey yapmıyor. –

cevap

46

time.sleep() sistemde daha az yük olacağını düşünürdüm. pass geçişi, döngünün hemen yeniden değerlendirmesini ve CPU'yu sabitlemesini sağlarken, time.sleep kullanılarak yürütmenin geçici olarak askıya alınmasına izin verilir.

DÜZENLEME: Eğer piton tercüman başlatıp bu çalıştırırsanız sadece kanıtlamak için:

>>> while True: 
...  pass 
... 

Python'u izleyebilirsiniz anında% 90-100 CPU yiyip başlar karşı:

>>> import time 
>>> while True: 
...  time.sleep(1) 
... 

Etkinlik İzleyicisi'nde (buradaki OS X'i kullanarak ancak her platform için aynı olmalıdır) neredeyse hiç kaydı yoktur.

+0

Teşekkürler, bunun böyle olduğunu anladım, ama belgelere geçmeyi görmeye devam ettim. –

4

Her zaman uyku kullanarak bunu yapmanın daha iyi bir yol olduğunu gördüm/duydum. Uyku kullanarak Python yorumcunuzun CPU kullanımının vahşi kalmasını engeller.

+0

Yup, mantıklı! –

6

Gerçekten ne yaptığınıza çok fazla bağlam vermezsiniz, ancak açık bir meşgul bekletme döngüsü yerine belki de Queue kullanılabilir? Değilse, daha az CPU tüketeceğine inandığım için (diğerlerinin de belirttiği gibi) sleep tercih edilebilir.

[aşağıda açıklamada ek bilgilere göre düzenlenmiştir.]

Belki bu açıktır, ama yine de, sen engelleme yuvalarına bilgi okuduğunuz bir durumda neler yapabileceğini bir iplik okuma sahip olmaktır soketten ve uygun biçimlendirilmiş mesajları bir Queue'a gönderin ve sonra "çalışan" iş parçacığınızın kalan kısmını o sıradan okuyarak geçirin; İşçiler daha sonra ne pass ne de sleep'a ihtiyaç duymadan sıradan okumaya engel olacaklar.

+0

Kuyruktaki ipucu için kullanışlı olduğunu düşündüğünüz için, bu uygulamada bir AMQP aracısından gelen mesajları (ayrı iş parçacıklarında) dinlemek ve bunları aldıktan sonra harekete geçirmek için kilitleme yuvaları kullanıyorum. –

+0

@Crad: Daha sonra, bir kuyruğun çalışmasına benzer bir yuvada beklemek için seçin. Yoğun beklemeyi veya yoklamayı kullanmayın. –

22

Neden uyuyalım? Uyumak istemiyor, iş parçacığının bitmesini beklemek istiyorsun.

Yani

# store the threads you start in a your_threads list, then 
for a_thread in your_threads: 
    a_thread.join() 

Bkz: Bir kısa, sıfır cpu arıyorsanız thread.join

+1

İpliklerin bitmesini beklemiyorum. Bu bitmeyen bir süreçtir. Bu mantık hala geçerli mi? –

+0

Tabi ki mantık hala geçerli. "İlmekli" bir uyku için birkaç döngü bile israf etmekten kaçınırsınız. – tzot

+0

Bu işe yaramaz, çünkü iş parçacığı sonlandırılmamalı, süreç sonlandırılmalı, zaman aşımı kavramsal olarak her zaman ilk önce gelebilir mi, yoksa bir şey mi eksik? –

0

Python

import threading 
    import time 


    class ThreadingExample(object): 
     """ Threading example class 
     The run() method will be started and it will run in the background 
     until the application exits. 
     """ 

     def __init__(self, interval=1): 
      """ Constructor 
      :type interval: int 
      :param interval: Check interval, in seconds 
      """ 
      self.interval = interval 

      thread = threading.Thread(target=self.run, args=()) 
      thread.daemon = True       # Daemonize thread 
      thread.start()         # Start the execution 

     def run(self): 
      """ Method that runs forever """ 
      while True: 
       # Do something 
       print('Doing something imporant in the background') 

       time.sleep(self.interval) 

    example = ThreadingExample() 
    time.sleep(3) 
    print('Checkpoint') 
    time.sleep(2) 
    print('Bye') 
2

uyku ile bir arka plan iş parçacığı gibi bir yöntem Running Bir KeyboardInterrupt kadar sonsuza kadar döngü yolu, kullanabilirsiniz:

def do_task(): 
    sleep(10) 
    print('Task complete.') 
    event.set() 

event = Event() 
Thread(do_task).start() 
event.wait() 

print('Continuing...') 

yazdırır Hangi: Bazı arka plan için

from threading import Event 

Event().wait() 
, Event nesneler normalde tamamlamak için uzun çalışan süreçleri bekliyor kullanılan

Task complete. 
Continuing... 
İlgili konular