概述
本文讲解 共享内存 的方式实现 进程 间 通信
特点:
共享内存是最为 高效 的 进程 间 通信 方式,进程可以直接 读写内存,而不需要任何数据的拷贝。
为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。进程就可以直接读写这一块内存而不需要进行数据的拷贝,从而大大提高效率。
多个进程 读写内存 时需要 同步机制 确保正确。
优点:
快速在进程间传递数据
缺点:
数据安全上存在风险,内存中的内容会被其他进程 覆盖 或者 篡改
实现
通过 Value 和 Array 实现
Value
将 一个值 放入内存中,如:字符、数字、浮点型,但不可以是 字符串
所在文件:sharedctypes.py
导入模块:
from multiprocessing import Value
语法:
Value(typecode_or_type, *args, lock=True)
参数:
- typecode_or_type:指定类型(需要调用操作系统函数,所以要指定类型),参见链接:http://www.malaoshi.top/show_1EF2op2vGBGQ.html
- args:开辟一个空间,并赋一个args值,值得类型不限
返回:
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
