2014-02-14 74 views
1

我正在使用multiprocessing.Process啓動多個服務器。服務器地址全部在字典中定義,我希望它們全部同時運行。我希望找到一種簡單的方法來檢測其中一個服務器進程何時終止,出於某種原因並重新啓動它們。我到目前爲止的一個例子是:使用多處理進程啓動多個服務器。檢查進程是否已終止

from multiprocessing import Process 

server_dict = {"server1": "localhost, 9998", "service2": "localhost, 9999"} 
running_servers = {} 

def start_server(server_addr): 
    server = Server(server_dict[key], RequestHandlerClass) 
    p = Process(target=server.serve_forever()) 
    p.start() 
    running_servers[key]= p 


for key in server_dict: 
    start_server(server_dict[key]) 

while True : 
    for key in running_servers: 
     if not running_servers[key].is_alive(): 
      start_server(server_dict[key]) 

這個工程,但我必須有更好的方式來做到這一點。我不想經常檢查過程是否存在。

+0

您正在循環遍歷其中的鍵('for for key in running_servers')的內部循環中更改'running_servers'的內容('start_server'的確如此)。這可能是不好的,你的第二個循環也應該是'for key in server_dict' –

+0

我認爲這不重要,因爲一旦進程不再活着,我只會更改'running_servers'內容。 – plover

+0

只要你不改變密鑰,它就可以工作。該建議旨在防止您無意中做到這一點。 *在添加或刪除字典中的條目時使用iterkeys()可能會引發RuntimeError或無法遍歷所有條目* [請參見http://docs.python.org/2/library/stdtypes.html#dict.iterkeys]( 'for x in dict'相當於'for x in dict.iterkeys()' –

回答

0

我建議的唯一變化是:

  1. while True環內,但for循環外插入到time.sleep通話。根據您想要重新啓動已終止的服務器的速度選擇延遲值。這會阻止您的程序廣泛且不必要地使用CPU時間。在這種情況下使用sleep是非常常見的編碼模式。

  2. 不要遍歷running_servers。迭代tuple(running_servers.keys())tuple僅適用於Python 3,其中keys()返回迭代器)。

其他可能的選擇是使用一個線程池,每個進程一個線程。等待單個進程終止並重新啓動它通常不是問題。不幸的是,沒有可用於Windows'WaitForMultipleObjects() API調用的便攜式替代方案。

這些解決方案似乎是可移植的,並且至少可以用於* nix和Windows。但如果你不需要可移植性,還有其他方法可以完成這項工作。 @ Helmut的評論顯示了一個* nix特定的解決方案。在Windows上,通常可以使用WaitForMultipleObjects

相關問題