【python】进程间的数据共享的方式

进程间的数据共享的方式

注意:在使用并发设计的时候尽可能的避免共享数据,尤其是在使用多进程的时候。如果真的有需求要共享数据

共享数据mutiprocessing提供了两种方式。

数据共享方式一:Shared memory

#数据可以用Value或Array存储在一个共享内存地图里,如下:
from  multiprocessing import  Process,Value,Array
def f(n,a):
    print(n.value)
    for i in range(len(a)):#循环传过来的参数a
        a[i]=-a[i]#让他变成负数
    print(a[:])#将这个列表的元素从头打印到尾部
if __name__ =="__main__":#判断运行的代码是否在主题模块中
    num=Value("f",1)
    #用Value方法实现数据共享,Value(typecode_or_type,*args)
        # 第一个参数是定义这个生产一个什么类型的数据。
        # 第二个参数你就是你要传递的参数,只能是一个普通参数(字符串或数字),不能是类似于列表的数据类型
    ar=Array("i",range(20))
    #用Array方法实现数据共享,Array(typecode_or_type,size_or_initializer)
        # 第一个参数是定义这个生产一个什么类型的列表数据,每一个元素是什么类型数据。
        # 第二个参数你就是你要传递的参数,列表元组什么的..
    one=Process(target=f,args=(num,ar))
    two=Process(target=f,args=(num,ar))
    one.start()#让进程开始
    two.start()#让进程开始
    one.join()
    two.join()
结果为:
1.0
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19]
1.0
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

 

数据共享方式二:serverprocess

#主要依靠Manager来实现
from  multiprocessing import  Process,Manager

def f(d,l):
    d[1]="a"
    d[2]="b"
    d[3]="c"
    d[4]="d"
    l.reverse()

if __name__=='__main__':
    with Manager() as man:
        d=man.dict()#创建一个字典
        l=man.list(range(10))#创建一个列表
        print(l)
        p=Process(target=f,args=(d,l))#创建一个进程并把参数传过去
        p.start()#让进程开始
        p.join()
        print(l)
结果为:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
{1: 'a', 2: 'b', 3: 'c', 4: 'd'}

 进程共享数据的时候需要注意:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from  multiprocessing import Process,Manager
import  time
def f(a,i):
    a[i]=i
    print(a)
if __name__=="__main__":
    dic=Manager().dict()
    for i in  range(2):
        t=Process(target=f,args=(dic,i))
        t.start()
        t.join()#这里的join是为了控制要等待所有的子进程执行完毕后才让主进程结束
#如果上面的代码没有join()则会发生报错,因为实现进程数据共享的dic在主进程里面↓
#如果子进程要修改这个dic字典就必须要连接上主进程才可以修改,如果要连上主进程↓
#就不能让主进程结束,当代码从上到下执行完毕后,主进程就会自动结束,所以子进程无法连接上主进程所以就会发生报错
#如果不用join()方法也可以用time.sleep(300)来替代,这样不让主进程结束就不会报错

 

posted @ 2017-07-07 11:37  丰study  阅读(408)  评论(0)    收藏  举报