探究Python多進程編程下線程之間變數的共用問題

來源:互聯網
上載者:User
1、問題:

群中有同學貼了如下一段代碼,問為何 list 最後列印的是空值?

from multiprocessing import Process, Managerimport os manager = Manager()vip_list = []#vip_list = manager.list() def testFunc(cc):  vip_list.append(cc)  print 'process id:', os.getpid() if __name__ == '__main__':  threads = []   for ll in range(10):    t = Process(target=testFunc, args=(ll,))    t.daemon = True    threads.append(t)   for i in range(len(threads)):    threads[i].start()   for j in range(len(threads)):    threads[j].join()   print "------------------------"  print 'process id:', os.getpid()  print vip_list

其實如果你瞭解 python 的多執行緒模式,GIL 問題,然後瞭解多線程、多進程原理,上述問題不難回答,不過如果你不知道也沒關係,跑一下上面的代碼你就知道是什麼問題了。

python aa.pyprocess id: 632process id: 635process id: 637process id: 633process id: 636process id: 634process id: 639process id: 638process id: 641process id: 640------------------------process id: 619[]

將第 6 行注釋開啟,你會看到如下結果:

process id: 32074process id: 32073process id: 32072process id: 32078process id: 32076process id: 32071process id: 32077process id: 32079process id: 32075process id: 32080------------------------process id: 32066[3, 2, 1, 7, 5, 0, 6, 8, 4, 9]

2、python 多進程共用變數的幾種方式:
(1)Shared memory:
Data can be stored in a shared memory map using Value or Array. For example, the following code

http://docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes

from multiprocessing import Process, Value, Array def f(n, a):  n.value = 3.1415927  for i in range(len(a)):    a[i] = -a[i] if __name__ == '__main__':  num = Value('d', 0.0)  arr = Array('i', range(10))   p = Process(target=f, args=(num, arr))  p.start()  p.join()   print num.value  print arr[:]

結果:

3.1415927[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

(2)Server process:

A manager object returned by Manager() controls a server process which holds Python objects and allows other processes to manipulate them using proxies.
A manager returned by Manager() will support types list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Queue, Value and Array.
代碼見開頭的例子。

http://docs.python.org/2/library/multiprocessing.html#managers
3、多進程的問題遠不止這麼多:資料的同步

看段簡單的代碼:一個簡單的計數器:

from multiprocessing import Process, Managerimport os manager = Manager()sum = manager.Value('tmp', 0) def testFunc(cc):  sum.value += cc if __name__ == '__main__':  threads = []   for ll in range(100):    t = Process(target=testFunc, args=(1,))    t.daemon = True    threads.append(t)   for i in range(len(threads)):    threads[i].start()   for j in range(len(threads)):    threads[j].join()   print "------------------------"  print 'process id:', os.getpid()  print sum.value

結果:

------------------------process id: 1737897

也許你會問:WTF?其實這個問題在多線程時代就存在了,只是在多進程時代又杯具重演了而已:Lock!

from multiprocessing import Process, Manager, Lockimport os lock = Lock()manager = Manager()sum = manager.Value('tmp', 0)  def testFunc(cc, lock):  with lock:    sum.value += cc  if __name__ == '__main__':  threads = []   for ll in range(100):    t = Process(target=testFunc, args=(1, lock))    t.daemon = True    threads.append(t)   for i in range(len(threads)):    threads[i].start()   for j in range(len(threads)):    threads[j].join()   print "------------------------"  print 'process id:', os.getpid()  print sum.value

這段代碼效能如何呢?跑跑看,或者加大迴圈次數試一下。。。
4、最後的建議:

Note that usually sharing data between processes may not be the best choice, because of all the synchronization issues; an approach involving actors exchanging messages is usually seen as a better choice. See also Python documentation: As mentioned above, when doing concurrent programming it is usually best to avoid using shared state as far as possible. This is particularly true when using multiple processes. However, if you really do need to use some shared data then multiprocessing provides a couple of ways of doing so.

5、Refer:

http://stackoverflow.com/questions/14124588/python-multiprocessing-shared-memory

http://eli.thegreenplace.net/2012/01/04/shared-counter-with-pythons-multiprocessing/

http://docs.python.org/2/library/multiprocessing.html#multiprocessing.sharedctypes.synchronized

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.