Python进程间通信(IPC)详解:管道、队列、共享内存与信号量
本文详细介绍Python中进程间通信(IPC)的四种核心机制:管道、消息队列、共享内存和信号量。通过原理说明与代码演示,解析各方法的适用场景、实现步骤及注意事项,涵盖Linux环境下的具体操作与Windows限制,帮助开发者掌握多进程数据交互的关键技术。
进程间通信(IPC)
必要性
由于进程拥有独立的内存空间,彼此资源不共享,因此在需要跨进程传输数据时,必须采用特定的通信机制来实现数据交互。
常用进程间通信方法
常见的IPC方式包括:管道(Pipe)、消息队列(Queue)、共享内存(Shared Memory)、信号量(Semaphore)以及套接字(Socket)。
管道通信(Pipe)
1.通信原理
系统会在内存中开辟一段管道空间,并生成对应的管道操作对象。多个进程通过读写同一个管道对象,即可实现数据的传输与通信。
代码演示(windows 无效 linux 可用)
"""
pipe.py 管道通信
注意
1. multiprocessing 中管道通信只能用于有亲缘关系进程中
2. 管道对象在父进程中创建,子进程通过父进程获取
"""
from multiprocessing import Process, Pipe
# 创建 管道
fd1, fd2 = Pipe()
def app1():
print('1 启动应用1,请登录')
print('2 请求app2授权')
fd1.send('app1 请求登录')
data = fd1.recv()
print('5 ??',data)
if data:
print('6 登录成功:', data)
def app2():
print('2.5')
# 阻塞等待读取管道内容
data = fd2.recv()
print('3 app2', data)
fd2.send(('Dave', '123'))
print('4 app2,发送完毕')
if __name__ == '__main__':
print(-5)
p1 = Process(target=app1)
print(-4)
p2 = Process(target=app2)
print(-3)
p1.start()
print(-2)
p2.start()
print(-1)
p1.join()
print(0)
p2.join()
print('运行结束')
"""
运行结果
(base) [root@VM-0-12-centos pipe]# python pipe.py
-5
-4
-3
-2
-1
1 启动应用1,请登录
2 请求app2授权
2.5
3 app2 app1 请求登录
4 app2,发送完毕
5 ?? ('Dave', '123')
6 登录成功: ('Dave', '123')
0
运行结束
"""
消息队列
在内存中构建一个队列模型,进程通过将消息存入队列或从队列中取出消息,从而完成进程间的数据通信。
2. 实现方法
"""
quque_test.py 消息队列演示
注意: 消息队列符合先进先出原则
"""
# 创建消息队列
from multiprocessing import Queue, Process
from random import randint
# 以下模拟 双色球
# 创建消息队列
q = Queue(5)
def handle():
print(5)
for i in range(6):
q.put(randint(1, 33))
q.put(randint(1, 16))
def request():
print(6)
l = [q.get() for i in range(6)]
l.sort()
l.append(q.get())
print(7,l)
if __name__ == '__main__':
print(0)
p1 = Process(target=handle)
print(1)
p2 = Process(target=request)
print(2)
p1.start()
print(3)
p2.start()
print(4)
p1.join()
p2.join()
print(8)
print('程序结束')
控制台输出 linux (windows无效)

共享内存
1.通信原理
系统在内存中开辟一块共享空间,进程可在此写入或读取数据以完成通信。需要注意的是,每次写入新内容通常会覆盖之前的数据。
2.实现方法

主要使用Value和Array两个类来实现共享内存的创建与管理。
from multiprocessing import Value,Array
obj = Value(ctype,data)
功能: 开辟共享内存
参数: ctype 表示共享内存空间类型 'i' 'f' 'c'
data 共享内存空间初始数据
返回值: 共享内存对象
obj.value 对象属性的修改查看即对共享内存读写
obj = Array(ctype,data)
功能: 开辟共享内存
参数: ctype 表示共享内存空间类型 'i' 'f' 'c'
data 整数表示开辟空间的大小,其数据表示开辟空间
返回值: 共享内存对象
Array共享内存读写:通过遍历obj可以得到每个值,直接通过索引可以修改
* 可以使用obj.value 直接打印共享内存中的字节串
value 代码 演示
"""
value.py 开辟单一共享内存空间
注意:共享内存只能有一个值
"""
from multiprocessing import Value,Array,Process
import time
import random
ctype = 'i'
data = 5000
# 创建共享内存
money = Value(ctype,data)
# 操作共享内存
def man():
for i in range(30):
time.sleep(0.1)
money.value += random.randint(1,1000)
print('man',money.value)
def girl():
for i in range(30):
time.sleep(0.1)
money.value -= random.randint(1,800)
print('girl', money.value)
if __name__ == '__main__':
p1 = Process(target=man)
p2 = Process(target=girl)
p1.start()
p2.start()
p1.join()
p2.join()
print('程序结束',money.value)
array 代码演示
"""
array.py 开辟单一共享内存空间
注意:共享内存只能有一个值
"""
from multiprocessing import Array,Process
ctype = 'i'
data = [1,2,3,4]
# 创建共享内存
# shm = Array(ctype,data)
# 表示初始值 [0,0,0,0,0]
shm = Array(ctype,5)
def fun():
for i in shm:
print(i)
shm[1] = 1000
if __name__ == '__main__':
p1 = Process(target=fun)
p1.start()
p1.join()
print('程序结束',shm[1])
信号量(信号灯集)
1.通信原理
系统提供一个多个进程可见的数值计数器,各进程均可对该数值进行增减操作,并根据当前的数值状态来决定自身的行为(如阻塞或继续执行)。
2. 实现方法
from multiprocessing import Semaphore
sem = Semaphore(num)
功能: 创建信号量对象
参数: 信号量的初始值
返回值: 信号量对象
sem.acquire() 信号量减1 当信号量为0时阻塞
sem.release() 信号量加1
sem.get_value() 获取信号量数量
3.代码演示
"""
信号量.py 信号量演示
思路: 信号量数量相当于资源,执行任务必须消耗资源
"""
import os
from multiprocessing import Semaphore
from multiprocessing import Process
from time import sleep
num = 3
sem = Semaphore(num)
# 任务函数
def handle():
sem.acquire() # sem -1
print("%s 开始执行任务" % os.getpid())
sleep(3)
print("%s 执行任务完毕" % os.getpid())
sem.release() # sem +1
if __name__ == '__main__':
ths = []
for i in range(10):
p = Process(target=handle)
p.start()
ths.append(p)
for p in ths:
p.join()
print('程序结束')
控制台运行结果

到此这篇关于python中进程间通信详细介绍的文章就介绍到这了,更多相关python进程间通信内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













