Python多进程-进程间共享数据

Python多进程-进程间共享数据

Python 多线程之间共享变量很简单,直接定义全局 global 变量即可。而多进程之间是相互独立的执行单元,这种方法就不可行了。

不过 Python 标准库已经给我们提供了这样的能力,使用起来也很简单。但要分两种情况来看,一种是 Process 多进程,一种是 Pool 进程池的方式。

Process 多进程

使用 Process 定义的多进程之间共享变量可以直接使用 multiprocessing 下的 Value,Array,Queue 等,如果要共享 list,dict,可以使用强大的 Manager 模块。

import multiprocessing


def func(num):
    # 共享数值型变量
    # num.value = 2

    # 共享数组型变量
    num[2] = 9999


if __name__ == '__main__':
    # 共享数值型变量
    # num = multiprocessing.Value('d', 1)
    # print(num.value)

    # 共享数组型变量
    num = multiprocessing.Array('i', [1, 2, 3, 4, 5])
    print(num[:])

    p = multiprocessing.Process(target=func, args=(num,))
    p.start()
    p.join()

    # 共享数值型变量
    # print(num.value)

    # 共享数组型变量
    print(num[:])

Pool 进程池

进程池之间共享变量是不能使用上文方式的,因为进程池内进程关系并非父子进程,想要共享,必须使用 Manager 模块来定义。

from multiprocessing import Pool, Manager


def func(my_list, my_dict):
    my_list.append(10)
    my_list.append(11)
    my_dict['a'] = 1
    my_dict['b'] = 2


if __name__ == '__main__':
    manager = Manager()
    my_list = manager.list()
    my_dict = manager.dict()

    pool = Pool(processes=2)
    for i in range(0, 2):
        pool.apply_async(func, (my_list, my_dict))
    pool.close()
    pool.join()

    print(my_list)
    print(my_dict)

还有一点需要注意,在共享 list 时,像下面这样写 func 是不起作用的。

def func(my_list, my_dict):
    my_list = [10, 11]
    my_dict['a'] = 1
    my_dict['b'] = 2

这样写相当于重新定义了一个局部变量,并没有作用到原来的 list 上,必须使用 append,extend 等方法。

case2

Value、Array是通过共享内存的方式共享数据
Manager是通过共享进程的方式共享数据。

Value\Array
实例代码:

import multiprocessing
#Value/Array
def func1(a,arr):
    a.value=3.14
    for i in range(len(arr)):
        arr[i]=-arr[i]
if __name__ == '__main__':
    num=multiprocessing.Value('d',1.0)#num=0
    arr=multiprocessing.Array('i',range(10))#arr=range(10)
    p=multiprocessing.Process(target=func1,args=(num,arr))
    p.start()
    p.join()
    print num.value
    print arr[:]

执行结果:

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

Manager管理的共享数据类型有:Value、Array、dict、list、Lock、Semaphore等等,同时Manager还可以共享类的实例对象。

实例代码:

from multiprocessing import Process,Manager
def func1(shareList,shareValue,shareDict,lock):
    with lock:
        shareValue.value+=1
        shareDict[1]='1'
        shareDict[2]='2'
        for i in xrange(len(shareList)):
            shareList[i]+=1

if __name__ == '__main__':
    manager=Manager()
    list1=manager.list([1,2,3,4,5])
    dict1=manager.dict()
    array1=manager.Array('i',range(10))
    value1=manager.Value('i',1)
    lock=manager.Lock()
    proc=[Process(target=func1,args=(list1,value1,dict1,lock)) for i in xrange(20)]
    for p in proc:
        p.start()
    for p in proc:
        p.join()
    print list1
    print dict1
    print array1
    print value1
    
执行结果:

[21, 22, 23, 24, 25]
{1: '1', 2: '2'}
array('i', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Value('i', 21)
1
2
3
4

通过Manager进程间共享实例对象:

from multiprocessing import Process,Value,Lock
from multiprocessing.managers import BaseManager
class Employee(object):
    def __init__(self,name,salary):
        self.name=name
        self.salary=Value('i',salary)
    def increase(self):
        self.salary.value+=100
    def getPay(self):
        return self.name+':'+str(self.salary.value)
class MyManager(BaseManager):
    pass
def Manager2():
    m=MyManager()
    m.start()
    return m
MyManager.register('Employee',Employee)

def func1(em,lock):
    with lock:
        em.increase()

if __name__ == '__main__':
    manager=Manager2()
    em=manager.Employee('zhangsan',1000)
    lock=Lock()
    proces=[Process(target=func1,args=(em,lock))for i in xrange(10)]
    for p in proces:
        p.start()
    for p in proces:
        p.join()
    print em.getPay()
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值