多線程和多進程最大的不一樣在於,多進程中,同一個變量,各自有一份拷貝存在於每一個進程中,互不影響,而多線程中,全部變量都由全部線程共享,因此,任何一個變量均可以被任何一個線程修改,所以,線程之間共享數據最大的危險在於多個線程同時改一個變量,把內容給改亂了。python
不一樣進程之間內存是不共享的,要實現兩個進程間的數據交換,能夠用如下方法:服務器
使用方法和threading裏面的queue差很少多線程
from multiprocessing import Process,Queue def f(q): q.put([2,None,'hello']) if __name__ =='__main__': q = Queue() p = Process(target=f,args=(q,)) p.start() print(q.get()) p.join()
運行結果app
[2, None, 'hello']
多進程中,對於一個變量,每一個進程都是複製了一份,因此每一個進程之間修改數據互不影響。 Queue()方法至關於第三方,把進程A的數據序列化後傳給進程B 反序列化獲得數據。並非一個共享的變量。而是實現了數據的傳遞。socket
相似於socket 一端發送,一端接收,實現通訊。spa
from multiprocessing import Process,Pipe def f(conn): conn.send([5,'hello']) conn.close() if __name__ =='__main__': parent_conn,child_conn = Pipe() p = Process(target=f,args=(child_conn,)) p.start() print(parent_conn.recv()) p.join()
運行結果線程
[5, 'hello']
發送方和接收方的關係,也和socket相似,發送方發送幾回,接收方就要接收幾回。接收方若是接收的次數多於發送方,那麼接收方就會卡住,直到發送方在發送一次。代理
相互通訊對象
def f(conn): conn.send([5,'hello']) #發送數據 print(conn.recv()) #接收數據 conn.close() if __name__ =='__main__': parent_conn,child_conn = Pipe() p = Process(target=f,args=(child_conn,)) p.start() print(parent_conn.recv()) #接收數據 parent_conn.send("hehe你好") #發送數據 p.join()
Managersblog
由manager()返回的manager對象控制一個包含Python對象的服務器進程,並容許其餘進程使用代理來操做它們。
由manager()返回的管理器將支持類型列表、命令、名稱空間、鎖、RLock、信號量、BoundedSemaphore、Condition、Event、Barrier、Queue、Value和Array。
from multiprocessing import Process, Manager def f(d, l): d[1] = '1' d['2'] = 2 d[0.25] = None l.append(1) print(l) if __name__ == '__main__': with Manager() as manager: d = manager.dict() #生成一個字典,能夠在多個進程中傳遞和共享。 l = manager.list(range(5)) #生成一個列表,在多個進程中傳遞和共享。 p_list = [] #存放進程對象 for i in range(10): p = Process(target=f, args=(d, l)) p.start() p_list.append(p) for res in p_list: res.join() #等待進程結束 print(d) print(l)
運行結果
[0, 1, 2, 3, 4, 1] [0, 1, 2, 3, 4, 1, 1] [0, 1, 2, 3, 4, 1, 1, 1] [0, 1, 2, 3, 4, 1, 1, 1, 1] [0, 1, 2, 3, 4, 1, 1, 1, 1, 1] [0, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1] [0, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1] [0, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1] [0, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1] [0, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] {0.25: None, 1: '1', '2': 2} [0, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
以上實現了進程之間的數據共享,不是數據傳遞,而是真正的共享。而且能夠同時修改。
Manager()內部有加鎖機制,不容許兩個進程同時修改一份數據,由於進程的數據是獨立的。