https://docs.python.org/zh-cn/3/library/multiprocessing.html
1共享内存基本例程
可以使用
Value
或Array
将数据存储在共享内存映射中。例如,以下代码:
1234567891011121314151617from
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))<br><code
class
=
"python plain"
> p.deamon<
/
code><code
class
=
"python keyword"
>
=
<
/
code><code
class
=
"python color1"
>
True
<
/
code> <code
class
=
"python comments"
>
#伴随主进程关闭而关闭</code>
p.start()
(num.value)
(arr[:])
2-1不同种类数据共享例程
https://blog.csdn.net/lechunluo3/article/details/79005910
Manager管理的共享数据类型有:Value、Array、dict、list、Lock、Semaphore等等,同时Manager还可以共享类的实例对象。
实例代码:
12345678910111213141516171819202122232425from
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
()
#存str类型数据
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()
list1
dict1
array1
value1
结果
1234[
21
,
22
,
23
,
24
,
25
]
{
1
:
'1'
,
2
:
'2'
}
array(
'i'
, [
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
])
Value(
'i'
,
21
)
2-2关于str类型数组共享内存的使用
1234567891011121314151617181920212223242526272829from
multiprocessing
import
Process,Manager
#1初始化共享内存
manager
=
Manager()
str_msg
=
manager.
dict
()
#存str类型数据
str_msg[
1
]
=
'0'
#用几个必须预先初始化 否则后面无法访问
str_msg[
2
]
=
'0'
#用几个必须预先初始化 否则后面无法访问
#2线程锁 保护多个线成对数据控制
lock
=
manager.Lock()
#3要执行的函数
def
func1(shareDict,lock):
with lock:
shareDict[
1
]
=
str
(
2
+
int
(shareDict[
1
]))
shareDict[
2
]
=
str
(
3
+
int
(shareDict[
2
]))
#4开启次线程 使用的函数+输入共享数据(str)+线程锁
proc
=
Process(target
=
func1,args
=
(str_msg,lock))
proc.deamon
=
True
#伴随主进程关闭
proc.start()
#开始
proc.join()
#加入线程池
#5主线程开启
while
1
:
(str_msg[
1
])
(str_msg[
2
])
3-1读两个串口,数据给共享内存
普通的读取(学习用实际不用,用类方便)
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273# -*- coding: utf-8 -*
import
serial
import
time
from
multiprocessing
import
Process, Value, Array
#读取温度和湿度
def
serial_th(num,arr):
ser
=
serial.Serial(
'/dev/ttyUSB1'
,
115200
)
if
ser.isOpen
=
=
False
:
ser.
open
()
# 打开串口
#ser.write(b"Raspberry pi is ready")
try
:
while
True
:
line
=
str
(ser.readline())
fengefu
=
'-'
a
=
line.strip().split(fengefu)
# x.strip()#除去每行的换行符 按照:分割
tv
=
"".join(a[
1
:
2
] ).strip()
# 去除空格
hv
=
"".join(a[
3
:
4
]).strip()
# 去除空格
arr[
0
]
=
int
(tv)
arr[
1
]
=
int
(hv)
#print('t-'+str(arr[0])+"-h-"+str(arr[1]))
#time.sleep(0.1) # 软件延时
except
KeyboardInterrupt:
ser.close()
#读取温度和湿度
def
serial_lmq29(num,arr):
ser
=
serial.Serial(
'/dev/ttyUSB0'
,
115200
)
if
ser.isOpen
=
=
False
:
ser.
open
()
# 打开串口
#ser.write(b"Raspberry pi is ready")
try
:
while
True
:
line
=
str
(ser.readline())
fengefu
=
'-'
a
=
line.strip().split(fengefu)
# x.strip()#除去每行的换行符 按照:分割
mq2
=
"".join(a[
1
:
2
] ).strip()
# 去除空格
light
=
"".join(a[
3
:
4
]).strip()
# 去除空格
mq9
=
"".join(a[
5
:
6
]).strip()
# 去除空格
#print(mq9)
arr[
2
]
=
int
(mq2)
arr[
3
]
=
int
(light)
arr[
4
]
=
int
(mq9)
#print('mq2-'+ str(arr[2]) +'-lihgt-'+str(arr[3])+'-mq9-'+str(arr[4]))
#time.sleep(0.1) # 软件延时
except
KeyboardInterrupt:
ser.close()
num_share
=
Value(
'd'
,
0.0
)
arr_share
=
Array(
'i'
,
range
(
5
))
p_wh
=
Process(target
=
serial_th, args
=
(num_share,arr_share))
p_wh.deamon
=
True
#伴随主进程关闭而关闭
p_wh.start()
p_l29
=
Process(target
=
serial_lmq29, args
=
(num_share,arr_share))
p_l29.deamon
=
True
p_l29.start()
while
1
:
# 打印共享内存数据
(arr_share[:])
3-2读两个串口,数据给共享内存,类的使用
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980# -*- coding: utf-8 -*
import
serial
import
time
from
multiprocessing
import
Process, Value, Array
class
Class_sensor:
def
__init__(
self
):
pass
#读取温度和湿度
def
serial_th(
self
,num,arr):
ser
=
serial.Serial(
'/dev/ttyUSB1'
,
115200
)
if
ser.isOpen
=
=
False
:
ser.
open
()
# 打开串口
#ser.write(b"Raspberry pi is ready")
try
:
while
True
:
line
=
str
(ser.readline())
fengefu
=
'-'
a
=
line.strip().split(fengefu)
# x.strip()#除去每行的换行符 按照:分割
tv
=
"".join(a[
1
:
2
] ).strip()
# 去除空格
hv
=
"".join(a[
3
:
4
]).strip()
# 去除空格
arr[
0
]
=
int
(tv)
arr[
1
]
=
int
(hv)
#print('t-'+str(arr[0])+"-h-"+str(arr[1]))
#time.sleep(0.1) # 软件延时
except
KeyboardInterrupt:
ser.close()
#读取温度和湿度
def
serial_lmq29(
self
,num,arr):
ser
=
serial.Serial(
'/dev/ttyUSB0'
,
115200
)
if
ser.isOpen
=
=
False
:
ser.
open
()
# 打开串口
#ser.write(b"Raspberry pi is ready")
try
:
while
True
:
line
=
str
(ser.readline())
fengefu
=
'-'
a
=
line.strip().split(fengefu)
# x.strip()#除去每行的换行符 按照:分割
mq2
=
"".join(a[
1
:
2
] ).strip()
# 去除空格
light
=
"".join(a[
3
:
4
]).strip()
# 去除空格
mq9
=
"".join(a[
5
:
6
]).strip()
# 去除空格
#print(mq9)
arr[
2
]
=
int
(mq2)
arr[
3
]
=
int
(light)
arr[
4
]
=
int
(mq9)
#print('mq2-'+ str(arr[2]) +'-lihgt-'+str(arr[3])+'-mq9-'+str(arr[4]))
#time.sleep(0.1) # 软件延时
except
KeyboardInterrupt:
ser.close()
def
class_int(
self
):
self
.num_share
=
Value(
'd'
,
0.0
)
self
.arr_share
=
Array(
'i'
,
range
(
5
))
p_wh
=
Process(target
=
self
.serial_th, args
=
(
self
.num_share,
self
.arr_share))
p_wh.deamon
=
True
#伴随主进程关闭而关闭
p_wh.start()
p_l29
=
Process(target
=
self
.serial_lmq29, args
=
(
self
.num_share,
self
.arr_share))
p_l29.deamon
=
True
p_l29.start()
t
=
Class_sensor()
#类的初始化
t.class_int()
#串口初始化
while
1
:
# 打印共享内存数据
(t.arr_share[:])
3-3字符类型的共享内存串口解析获取
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869'''
函数作用:
1开启其一个进程
2开启一个串口
3串口数据解析
4开辟共享内存 str 接收温度 湿度 mq2数据 (字符类型)
5主进程创建类调用这些数据
'''
# -*- coding: utf-8 -*
import
serial
import
time
from
multiprocessing
import
Process,Manager
class
Class_sensor:
def
__init__(
self
):
pass
#读取温度和湿度和MQ2烟雾火焰
def
serial_wsmq2(
self
,arr,clock):
ser
=
serial.Serial(
'/dev/ttyUSB0'
,
9600
)
if
ser.isOpen
=
=
False
:
ser.
open
()
# 打开串口
#ser.write(b"Raspberry pi is ready")
try
:
while
True
:
line
=
str
(ser.readline())
fengefu
=
'-'
a
=
line.strip().split(fengefu)
# x.strip()#除去每行的换行符 按照:分割
wendu
=
"".join(a[
1
:
2
] ).strip()
# 去除空格
shidu
=
"".join(a[
3
:
4
]).strip()
# 去除空格
mq2
=
"".join(a[
5
:
6
]).strip()
# 去除空格
#print(mq9)
with clock:
arr[
1
]
=
str
(wendu)
arr[
2
]
=
str
(shidu)
arr[
3
]
=
str
(mq2)
(
'温度-'
+
str
(arr[
1
])
+
'-湿度-'
+
str
(arr[
2
])
+
'-火焰烟雾-'
+
str
(arr[
3
]))
#time.sleep(0.1) # 软件延时
except
KeyboardInterrupt:
ser.close()
def
class_int(
self
):
#1初始化共享内存
self
.manager
=
Manager()
self
.str_msg
=
self
.manager.
dict
()
#存str类型数据
self
.str_msg[
1
]
=
'0'
#用几个必须预先初始化 否则后面无法访问
self
.str_msg[
2
]
=
'0'
#用几个必须预先初始化 否则后面无法访问
self
.str_msg[
3
]
=
'0'
#2线程锁 保护多个线成对数据控制
self
.lock
=
self
.manager.Lock()
p
=
Process(target
=
self
.serial_wsmq2, args
=
(
self
.str_msg,
self
.lock))
p.deamon
=
True
#伴随主进程关闭而关闭
p.start()
#共享内存测试
t
=
Class_sensor()
#类的初始化
t.class_int()
#串口初始化
(t.str_msg[
1
])
#调用数据
(t.str_msg[
2
])
#调用数据
(t.str_msg[
3
])
#调用数据
3-4 python多进程共享变量,附共享图像内存实例
https://www.cnblogs.com/banrixianxin/p/6781162.html
12345678910111213141516171819202122232425262728293031323334353637import
numpy as np
import
cv2, multiprocessing, sharedmem
def
show_image(image_in):
while
1
:
cv2.imshow(
"avi"
,image_in)
cv2.waitKey(
1
)
def
aa(images):
while
1
:
for
i
in
range
(
20
):
cv2.imshow(
"a"
,images[i])
cv2.waitKey(
1
)
if
__name__
=
=
'__main__'
:
cap
=
cv2.VideoCapture(
'1.avi'
)
assert
cap.isOpened(),
'Cannot capture source'
_, image
=
cap.read()
shape
=
np.shape(image)
dtype
=
image.dtype
images
=
multiprocessing.Manager().
dict
()
image_in
=
sharedmem.empty(shape, dtype)
image_in[:]
=
image.copy()
a
=
multiprocessing.Process(target
=
show_image,args
=
(image_in,))
a.start()
count
=
0
for
i
in
range
(
20
):
ret, image
=
cap.read()
if
not
ret:
break
image_in[:]
=
image.copy()
images[count]
=
image_in
count
+
=
1
multiprocessing.Process(target
=
aa, args
=
(images,)).start()
aa.join()
共享内存传图
主进程采集图像
次进程1显示图像
次进程2显示图像
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138#!/usr/bin/env python
# -*- coding=utf-8 -*-
import
cv2
import
zmq
import
base64
from
multiprocessing
import
Process,Manager
class
Class_camtcp:
def
__init__(
self
):
pass
def
Get_vedio(
self
,images,clock):
#初期化USB摄像头
#两路不卡最大分辨率
#w=600
#h=450
#四路不卡最大分辨率
w
=
480
h
=
320
fps
=
25
self
.cap
=
cv2.VideoCapture(
self
.VedioId)
self
.cap.
set
(cv2.CAP_PROP_FRAME_WIDTH, w)
self
.cap.
set
(cv2.CAP_PROP_FRAME_HEIGHT, h)
self
.cap.
set
(cv2.CAP_PROP_FPS, fps)
# cv2.namedWindow(str(self.VedioId),0);
#初始化传输
self
.contest
=
zmq.Context()
"""zmq对象使用TCP通讯协议"""
self
.footage_socket
=
self
.contest.socket(zmq.PAIR)
"""zmq对象和视频接收端建立TCP通讯协议"""
self
.vedio_url
=
'tcp://%s:'
%
self
.IP
+
str
(
self
.Port)
self
.footage_socket.connect(
self
.vedio_url)
images[
1
]
=
1
while
(
self
.cap.isOpened()):
#USB摄像头工作时,读取一帧图像
ret, frame
=
self
.cap.read()
with clock:
images[
int
(
self
.CamID)]
=
frame
if
self
.VedioShow
=
=
1
:
#显示图像窗口在树莓派的屏幕上
cv2.imshow(
str
(
self
.CamID),frame)
#按下q键退出
key
=
cv2.waitKey(
1
)
if
key &
0x00FF
=
=
ord
(
'q'
):
images[
0
+
int
(
self
.CamNum)]
=
0
images[
1
+
int
(
self
.CamNum)]
=
0
images[
2
+
int
(
self
.CamNum)]
=
0
images[
3
+
int
(
self
.CamNum)]
=
0
break
if
images[
int
(
self
.CamNum)
+
int
(
self
.CamID)]
=
=
0
:
break
encoded,
buffer
=
cv2.imencode(
'.jpg'
, frame)
#把转换后的图像数据再次转换成流数据,
jpg_as_test
=
base64.b64encode(
buffer
)
#把内存中的图像流数据进行base64编码
self
.footage_socket.send(jpg_as_test)
#把编码后的流数据发送给视频的接收端
# 释放资源和关闭窗口
self
.cap.release()
cv2.destroyAllWindows()
def
class_int(
self
,IP,Port,VedioId,show,ShareImages,CamID):
self
.CamNum
=
4
#总相机数目
# 获取基本信息
self
.IP
=
IP
#视频接受端的IP地址
self
.Port
=
Port
#视频接受端的IP端口 5555
self
.VedioId
=
VedioId
#打开的系统设备管理默认分配的视频编号 0 2 4 6 设备号默认的 实际需要查看lsusb
self
.VedioShow
=
show
#是否显示图像窗口调试 实际应取消减少运算浪费
#ShareImages 共享内存图像用于获取该路图像
self
.CamID
=
CamID
#相机编号 人为定义
msg
=
"IP:"
+
str
(
self
.IP )
+
" Port:"
+
str
(
self
.Port)
+
" CamId:"
+
str
(
self
.VedioId )
+
" CamShow:"
+
str
(
self
.VedioShow)
(msg )
#创建共享内存变量
self
.lock
=
Manager().Lock()
#创建共享内存容器
#self.ShareImages=Manager().dict()#存str类型数据
#创建线程
p
=
Process(target
=
self
.Get_vedio, args
=
(ShareImages,
self
.lock))
p.deamon
=
True
#伴随主进程关闭而关闭
p.start()
pass
Sever_Ip
=
'192.168.137.1'
CamNum
=
4
#总相机数目
showimg
=
0
#是否打开每路画面查看调试
ShareImages
=
Manager().
dict
()
#存str类型数据
img
=
cv2.imread(
"timg.jpg"
,
1
)
ShareImages[
0
]
=
img
#初始化共享内存图像
ShareImages[
0
+
CamNum]
=
1
#用于控制相机是否开启
ShareImages[
1
]
=
img
#初始化共享内存图像
ShareImages[
1
+
CamNum]
=
1
#用于控制相机是否开启
ShareImages[
2
]
=
img
#初始化共享内存图像
ShareImages[
2
+
CamNum]
=
1
#用于控制相机是否开启
ShareImages[
3
]
=
img
#初始化共享内存图像
ShareImages[
3
+
CamNum]
=
1
#用于控制相机是否开启
t0
=
Class_camtcp()
#类的初始化
t0.class_int(Sever_Ip,
5559
,
0
,showimg,ShareImages,
0
)
#串口初始化
t1
=
Class_camtcp()
#类的初始化
t1.class_int(Sever_Ip,
5556
,
2
,showimg,ShareImages,
1
)
#串口初始化
t2
=
Class_camtcp()
#类的初始化
t2.class_int(Sever_Ip,
5557
,
4
,showimg,ShareImages,
2
)
#串口初始化
t3
=
Class_camtcp()
#类的初始化
t3.class_int(Sever_Ip,
5558
,
6
,showimg,ShareImages,
3
)
#串口初始化
while
True
:
#如果图片为空 赋予默认图像
if
ShareImages[
0
]
is
None
:
ShareImages[
0
]
=
img
if
ShareImages[
1
]
is
None
:
ShareImages[
1
]
=
img
if
ShareImages[
1
]
is
None
:
ShareImages[
1
]
=
img
if
ShareImages[
1
]
is
None
:
ShareImages[
1
]
=
img
cv2.imshow(
's'
, ShareImages[
0
])
#默认把图像1显示在窗口中,简单判断图像是否开启
key
=
cv2.waitKey(
1
)
#延时等待,防止出现窗口无响应
if
key &
0x00FF
=
=
ord
(
'q'
):
#按q退出关闭所有相机画面
ShareImages[
0
+
CamNum]
=
0
ShareImages[
1
+
CamNum]
=
0
ShareImages[
2
+
CamNum]
=
0
ShareImages[
3
+
CamNum]
=
0
break
cv2.destroyAllWindows()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY