欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

探究Python多進(jìn)程編程下線程之間變量的共享問(wèn)題

 更新時(shí)間:2015年05月05日 09:38:03   作者:xrzs  
這篇文章主要介紹了探究Python多進(jìn)程編程下線程之間變量的共享問(wèn)題,多進(jìn)程編程是Python學(xué)習(xí)進(jìn)階中的重要知識(shí),需要的朋友可以參考下

 1、問(wèn)題:

群中有同學(xué)貼了如下一段代碼,問(wèn)為何 list 最后打印的是空值?
 

from multiprocessing import Process, Manager
import 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

其實(shí)如果你了解 python 的多線程模型,GIL 問(wèn)題,然后了解多線程、多進(jìn)程原理,上述問(wèn)題不難回答,不過(guò)如果你不知道也沒(méi)關(guān)系,跑一下上面的代碼你就知道是什么問(wèn)題了。
 

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

將第 6 行注釋開(kāi)啟,你會(huì)看到如下結(jié)果:
 

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

2、python 多進(jìn)程共享變量的幾種方式:
(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[:]

結(jié)果:
 

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.
代碼見(jiàn)開(kāi)頭的例子。

http://docs.python.org/2/library/multiprocessing.html#managers
3、多進(jìn)程的問(wèn)題遠(yuǎn)不止這么多:數(shù)據(jù)的同步

看段簡(jiǎn)單的代碼:一個(gè)簡(jiǎn)單的計(jì)數(shù)器:
 

from multiprocessing import Process, Manager
import 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

結(jié)果:
 

------------------------
process id: 17378
97

也許你會(huì)問(wèn):WTF?其實(shí)這個(gè)問(wèn)題在多線程時(shí)代就存在了,只是在多進(jìn)程時(shí)代又杯具重演了而已:Lock!
 

from multiprocessing import Process, Manager, Lock
import 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

這段代碼性能如何呢?跑跑看,或者加大循環(huán)次數(shù)試一下。。。
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

相關(guān)文章

最新評(píng)論