2013-10-25 24 views
1

我是守護進程的新手,我在想如何讓我的主腳本成爲守護進程?如何使用具有while循環的守護進程?

我有我希望做一個守護進程在後臺運行,我的主要腳本:

main.py 

    def requestData(information): 
     return currently_crunched_data() 

    while True: 
      crunchData() 

我希望能夠循環運行時使用功能的RequestData這個守護進程。我不太熟悉守護進程或如何將我的腳本轉換爲一個。

但我猜我必須做兩個線程,一個用於我的cruncData循環,一個用於守護進程請求接收者,因爲守護進程有自己的循環(daemon.requestLoop())。

我目前正在研究Pyro來做到這一點。有誰知道我可以最終做一個後臺運行while循環有能力接收來自其他進程的請求(如我想的守護進程)?

+0

您使用的是Linux嗎? – Homer6

+0

我建議使用supervisord - 它避免了處理守護進程問題的需要。 – Marcin

+1

這裏有兩個單獨的問題。首先,「我該如何做兩件事」,是的,使用後臺線程是一種明顯的方式,並且可以工作。然後,有「如何在Python中編寫守護進程」,這是一個重複。所以,我會忽略第二個。 – abarnert

回答

2

在Python中創建一個守護進程已經有很多問題,比如this one,它很好地回答了這個問題。

那麼,你如何讓你的守護進程做後臺工作?

如您所懷疑的,線程是一個明顯的答案。但是有三種可能的複雜性。


首先,有關機。如果你幸運的話,你的功能可以在任何時候立即被殺死,沒有損壞的數據或(太重要的)失去工作。在這種情況下:

def worker(): 
    while True: 
     crunchData() 

# ... somewhere in the daemon startup code ... 
t = threading.Thread(target=worker) 
t.daemon = True 
t.start() 

請注意t.daemon。 A "daemon thread"與你的程序是一個守護進程無關;這意味着你可以退出主流程,它會被立即殺死。

但是如果crunchData不能被殺死呢?然後,你需要做這樣的事情:

quitflag = False 
quitlock = threading.Lock() 

def worker(): 
    while True: 
     with quitlock: 
      if quitflag: 
       return 
     crunchData() 

# ... somewhere in the daemon startup code ... 
t = threading.Thread(target=worker) 
t.start() 

# ... somewhere in the daemon shutdown code ... 
with quitlock: 
    quitflag = True 
t.join() 

我假設的crunchData每個迭代認爲並不需要很長時間。如果是這樣,您可能需要定期在功能本身內檢查quitFlag


同時,您希望您的請求處理程序訪問後臺線程正在生成的一些數據。你也需要一些同步。

顯而易見的是隻使用另一個Lock。但是很有可能的是crunchData正在頻繁地寫入數據。如果它一次持有鎖定10秒,則請求處理程序可能會阻塞10秒。但是,如果它抓住並釋放鎖定一百萬次,那可能比實際工作需要更長的時間。

一種替代方法是對您的數據進行雙緩衝:將crunchData寫入新副本,然後在完成後,暫時取鎖並設置currentData = newData

根據您的使用情況,Queue,文件或其他可能更簡單。


最後,crunchData大概是做了大量的CPU工作。您需要確保請求處理程序的CPU工作量非常小,或者每個請求都會減慢速度,因爲兩個線程都在GIL上進行爭奪。通常這是沒有問題的。如果是,請使用multiprocessing.Process而不是Thread(這會使兩個進程之間的數據共享或傳遞稍微複雜一些,但仍然不算太差)。