python-进程间通信-共享内存

概述

本文讲解 共享内存 的方式实现 进程 间 通信

特点:

  1. 共享内存是最为 高效 的 进程 间 通信 方式,进程可以直接 读写内存,而不需要任何数据的拷贝。

  2. 为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。进程就可以直接读写这一块内存而不需要进行数据的拷贝,从而大大提高效率。

  3. 多个进程 读写内存 时需要 同步机制 确保正确。

优点:

快速在进程间传递数据

缺点:

数据安全上存在风险,内存中的内容会被其他进程 覆盖 或者 篡改

实现

通过 Value 和 Array 实现

Value

将 一个值 放入内存中,如:字符、数字、浮点型,但不可以是 字符串

所在文件:sharedctypes.py

导入模块:

from multiprocessing import Value

语法:

Value(typecode_or_type, *args, lock=True)

参数:

返回:
Returns a synchronized shared object(同步共享对象)
通过.value获取值

简单例子:

from multiprocessing import Value

#i表示int型
num = Value('i',2000)
#修改值
num.value=3000
#取值
print(num.value)

#u表示字符,可以是汉字
text = Value('u','哈')
#修改值
text.value='呵'
#取值
print(text.value)

Value完整例子

一个进程修改公共变量,一个进程访问公共变量

#coding=utf-8
from multiprocessing import Process,Value
import time,os

def write(n):
    print('write()开始,pid=%d,num=%d'%(os.getpid(),n.value))
    #修改变量
    for index in range(10):
        n.value+=1
        time.sleep(0.1)
    print('write()结束,pid=%d,num=%d'%(os.getpid(),n.value))

def read(n):
    print('read()开始,pid=%d,num=%d'%(os.getpid(),n.value))
    #访问变量
    for index in range(10):
        print('read()循环,pid=%d,num=%d'%(os.getpid(),n.value))
        time.sleep(0.1)
    print('read()结束,pid=%d,num=%d'%(os.getpid(),n.value))
if __name__ == "__main__":
    num=Value('i',0)
    w=Process(target=write,args=(num,))
    r=Process(target=read,args=(num,))
    w.start()
    r.start()
    w.join()
    r.join()
    #主进程打印值
    print('主进程,num=%s'%num.value)

执行结果如下:

当一个进程修改变量,另一个进程访问变量时,其值也在变化,说明两个进程共享该变量

Array

将 多个值 放在内存中,但 数据类型必须一致

导入模块

from multiprocessing import Array

语法:

Array(typecode_or_type, size_or_initializer, *, lock=True, ctx=None)

参数:

  • typecode_or_type:指定要类型,同Value的参数
  • size_or_initializer:
    • 若为 数字,表示 开辟 的共享内存的 空间大小
    • 若为 数组,表示在 共享内存 中 存入数组

返回值:
同Value
通过[索引]获取值

例子:初始化时开辟空间大小

#coding=utf-8

from multiprocessing import Process,Array

def write(arr):
    print('在write()中修改值')
    for item in range(len(arr)):
        arr[item]=item*20

if __name__ == "__main__":
    #初始化时指定开辟空间大小
    arr=Array('i',3)
    r=Process(target=write,args=(arr,))
    r.start()
    r.join()
    print('主进程打印')
    for item in arr:
        print(item)

提问

上例的write()函数是否可以修改成下面代码:

def write(arr):
    #修改数组值
    for item in arr:
        item=1

例子:初始化时指定数组

#coding=utf-8

from multiprocessing import Process,Array

def write(arr):
    print('在write()中访问')
    for item in arr:
        print(item)

    print('在write()中修改值')
    for item in range(len(arr)):
        arr[item]=item*20

if __name__ == "__main__":
    #初始化时指定开辟空间大小
    arr=Array('i',[1,2,3])
    r=Process(target=write,args=(arr,))
    r.start()
    r.join()
    print('主进程打印')
    for item in arr:
        print(item)

感谢:
https://www.cnblogs.com/gengyi/p/8661235.html


原文出处:/show_1EF2osCm1aQw.html