2015-04-17 157 views
1

我有一個連接到websocket遠程服務器的對象。我需要同時進行並行處理。但是,我不想創建到服務器的新連接。由於線程是更簡單的方法,所以這是我迄今爲止所使用的。但是,由於GIL,我得到了巨大的延遲。我可以實現與線程相同的功能,但並行使用多進程嗎?多進程python與共享內存

這是我的代碼:

class WebSocketApp(object): 

    def on_open(self): 

    # Create another thread to make sure the commands are always been read 
    print "Creating thread..." 
    try: 
     thread.start_new_thread(self.read_commands,()) 
    except: 
     print "Error: Unable to start thread" 

有同等的方式與multiprocesses做到這一點?

謝謝!

+1

你試過['multiprocessing'模塊](https://docs.python.org/2.7/library/multiprocessing.html)嗎? – Johny

+0

是的,但我想弄清楚如何共享內存。我需要自己的對象是同一個實例,而不是不同的實例。 –

回答

1

你肯定可以,沿着線使用的東西:

from multiprocessing import Process 

class WebSocketApp(object): 

    def on_open(self): 

    # Create another thread to make sure the commands are always been read 
    print "Creating thread..." 
    try: 
     p = Process(target = WebSocketApp.read_commands, args = (self,)) # Add other arguments to this tuple 
     p.start() 
    except: 
     print "Error: Unable to start thread" 

然而,必須指出,重要的是,只要對象是在兩個對象發送到其他進程selfself不同的線程發散並表示不同的對象。如果您希望溝通,您需要使用multiprocessing模塊中包含的QueuePipe之類的內容。

您可能需要在主線程中保留所有進程(本例中爲p)的引用,以便能夠通知您的程序正在終止(因爲仍在運行的子進程會掛起父母死後),但這取決於你的程序的性質。

如果您想保留對象一樣,你可以做的幾件事情之一:

使您的所有對象屬性是單值或數組,然後做一些與此類似:

from multiprocessing import Process, Value, Array 

class WebSocketApp(object): 
    def __init__(self): 
     self.my_value = Value('d', 0.3) 
     self.my_array = Array('i', [4 10 4]) 

    # -- Snip -- 

然後這些值應該作爲共享內存。該類型是非常嚴格的,但(你必須指定它們的類型) 不同的答案是使用一個經理:爲共享內存中的列表和字典

from multiprocessing import Process, Manager 

class WebSocketApp(object): 
    def __init__(self): 
     self.my_manager = Manager() 
     self.my_list = self.my_manager.list() 
     self.my_dict = self.my_manager.dict() 

    # -- Snip -- 

然後self.my_listself.my_dict分別作用。

但是,這兩種方法的類型可能會受到限制,因此您可能需要使用QueueSemaphore來滾動自己的技術。但這取決於你在做什麼。

查看multiprocessing文檔以獲取更多信息。

+0

實際上,您並不需要保留對其進程的引用或調用'join「來終止主進程。只要子進程自行退出,您的主進程也可以退出。調用'p.join()'只是讓主進程阻塞,直到'p'完成,它實際上並不強制它退出。在退出之前,你的主程序會隱式調用任何非守護的孩子的「加入」。 – dano

+0

流程中的兩個不同對象「自我」是我試圖避免的。因爲我需要它是對象的同一個實例。什麼是最好的方式來實現這一目標? –

+0

@LuisCruz更新了更多的共享內存信息。 – meiamsome

1

直接等同是

import multiprocessing 

class WebSocketApp(object): 

    def on_open(self): 

    # Create another process to make sure the commands are always been read 
    print "Creating process..." 
    try: 
     multiprocessing.Process(target=self.read_commands,).start() 
    except: 
     print "Error: Unable to start process" 

然而,這並沒有解決「共享內存」方面,它有不同的處理稍微比它與線程,在那裏你可以使用全局變量。您還沒有真正指定需要在流程之間共享哪些對象,因此很難確切地說明您應採取什麼方法。然而,multiprocessing文檔涵蓋ways to deal with shared state。請注意,通常它是better to avoid shared state if possible,並且只是在進程之間明確地傳遞狀態,或者作爲構造函數的參數,或者通過類似Queue的東西。

+0

那麼我需要分享的對象基本上就是自我對象。如果我使用多進程,那麼傳遞的自身對象將是該對象的不同實例,這就是我想要避免的。 –