python 多線程和多進程的區別 mutiprocessing theading


多線程可以共享全局變量,多進程不能。多線程中,所有子線程的進程號相同;多進程中,不同的子進程進程號不同。

 1 #!/usr/bin/python
 2 # -*- coding:utf-8 -*-
 3 import os
 4 import threading
 5 import multiprocessing
 6 count_thread = 0
 7 count_process = 0
 8 
 9 # worker function
10 def worker1(sign, lock):
11     global count_thread
12     lock.acquire()
13     count_thread += 1
14     print(sign, os.getpid())
15     lock.release()
16 
17 def worker2(sign, lock):
18     global count_process
19     lock.acquire()
20     count_process += 1
21     print(sign, os.getpid())
22     lock.release()
23 # Main
24 print('Main:',os.getpid())
25 
26 # Multi-thread
27 record = []
28 lock  = threading.Lock()
29 for i in range(5):
30     thread = threading.Thread(target=worker1,args=('thread',lock))
31     thread.start()
32     record.append(thread)
33 
34 for thread in record:
35     thread.join()
36 
37 # Multi-process
38 record = []
39 lock = multiprocessing.Lock()
40 for i in range(5):
41     process = multiprocessing.Process(target=worker2,args=('process',lock))
42     process.start()
43     record.append(process)
44 
45 for process in record:
46     process.join()
47 
48 
49 print count_thread
50 print count_process
View Code

運行結果

('Main:', 3142)
('thread', 3142)
('thread', 3142)
('thread', 3142)
('thread', 3142)
('thread', 3142)
('process', 3148)
('process', 3149)
('process', 3150)
('process', 3151)
('process', 3152)
5
0

應該盡量避免多進程共享資源。多進程共享資源必然會帶來進程間相互競爭。而這種競爭又會造成race condition,我們的結果有可能被競爭的不確定性所影響。但如果需要,我們依然可以通過共享內存和Manager對象這么做。

1) 共享內存

用Python實現的例子:

 1 import multiprocessing
 2 
 3 def f(n, a):
 4     n.value   = 3.14
 5     a[0]      = 5
 6 
 7 num   = multiprocessing.Value('d', 0.0)
 8 arr   = multiprocessing.Array('i', range(10))
 9 
10 p = multiprocessing.Process(target=f, args=(num, arr))
11 p.start()
12 p.join()
13 
14 print num.value
15 print arr[:]
View Code

這里我們實際上只有主進程和Process對象代表的進程。我們在主進程的內存空間中創建共享的內存,也就是Value和Array兩個對象。對象Value被設置成為雙精度數(d), 並初始化為0.0。而Array則類似於C中的數組,有固定的類型(i, 也就是整數)。在Process進程中,我們修改了Value和Array對象。回到主程序,打印出結果,主程序也看到了兩個對象的改變,說明資源確實在兩個進程之間共享。

2)Manager

Manager對象類似於服務器與客戶之間的通信 (server-client),與我們在Internet上的活動很類似。我們用一個進程作為服務器,建立Manager來真正存放資源。其它的進程可以通過參數傳遞或者根據地址來訪問Manager,建立連接后,操作服務器上的資源。在防火牆允許的情況下,我們完全可以將Manager運用於多計算機,從而模仿了一個真實的網絡情境。下面的例子中,我們對Manager的使用類似於shared memory,但可以共享更豐富的對象類型。

 1 import multiprocessing
 2 
 3 def f(x, arr, l):
 4     x.value = 3.14
 5     arr[0] = 5
 6     l.append('Hello')
 7 
 8 server = multiprocessing.Manager()
 9 x    = server.Value('d', 0.0)
10 arr  = server.Array('i', range(10))
11 l    = server.list()
12 
13 proc = multiprocessing.Process(target=f, args=(x, arr, l))
14 proc.start()
15 proc.join()
16 
17 print(x.value)
18 print(arr)
19 print(l)
View Code

Manager利用list()方法提供了表的共享方式。實際上你可以利用dict()來共享詞典,Lock()來共享threading.Lock(注意,我們共享的是threading.Lock,而不是進程的mutiprocessing.Lock。后者本身已經實現了進程共享)等。 這樣Manager就允許我們共享更多樣的對象。

參考資料:

http://blog.csdn.net/zhaozhi406/article/details/8137670

http://www.xuebuyuan.com/1968817.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM