python进程间数据交互的几种实现方式
作者:处女座_三月 发布时间:2022-11-05 09:32:12
一 方法汇总
在 Python 进程中,有几种方法可以实现数据交互:
共享内存:这是一种用于进程间通信的高效方式。多个进程可以访问同一个共享内存区域,并在其中读取和写入数据。
管道(Pipe):这是一种用于进程间通信的基本方式。管道可以在两个进程之间传递数据。一个进程将数据写入管道,另一个进程从管道中读取数据。
队列(Queue):队列也是一种进程间通信的方式。一个进程将数据放入队列,另一个进程从队列中获取数据。
套接字(Socket):套接字是一种用于网络通信的方式,但它们也可以在同一台计算机上进行进程间通信。每个套接字都有一个唯一的地址,进程可以使用这个地址来发送和接收数据。
文件:进程可以使用文件作为数据交换的方式。一个进程将数据写入文件,另一个进程从文件中读取数据。
二 实际举例
2.1 共享内存
使用 multiprocessing.Value 可以创建进程间共享的变量,下面是一个例子,创建了一个类型为整数('i')的共享内存变量 value,然后启动 10 个进程去调用 func 函数,该函数会将 value 的值加 1。最后输出 value 的值,应该是 10:
import multiprocessing
def func(value):
value.value += 1
if __name__ == '__main__':
value = multiprocessing.Value('i', 0)
processes = [multiprocessing.Process(target=func, args=(value,)) for _ in range(10)]
for process in processes:
process.start()
for process in processes:
process.join()
print(value.value) # 输出 10
2.2 管道
使用 multiprocessing.Pipe 可以创建一个管道,两个进程可以通过这个管道互相传递数据,下面是一个例子,创建了一个管道,其中 parent_conn 是父进程持有的端口,child_conn 是子进程持有的端口。然后启动两个进程,分别调用 sender 和 receiver 函数。sender 函数发送一条消息到管道中,receiver 函数从管道中接收消息并打印出来:
import multiprocessing
def sender(conn):
conn.send('Hello, receiver')
def receiver(conn):
message = conn.recv()
print(message)
if __name__ == '__main__':
parent_conn, child_conn = multiprocessing.Pipe()
p1 = multiprocessing.Process(target=sender, args=(parent_conn,))
p2 = multiprocessing.Process(target=receiver, args=(child_conn,))
p1.start()
p2.start()
p1.join()
p2.join()
2.3 队列
使用 multiprocessing.Queue 可以创建一个进程间共享的队列,多个进程可以通过这个队列互相传递数据,下面是一个例子,创建了一个进程间共享的队列 q,然后启动了四个进程去调用 worker 函数,该函数会从队列中获取数据并打印出来。主进程向队列中发送 10 个数值,每个进程都会从队列中获取数据并进行处理。当主进程发送完所有内容后,向队列中发送 N 个 None 值(N 等于进程数量),以通知各进程退出:
import multiprocessing
def worker(q):
while True:
item = q.get()
if item is None:
break
print(item)
if __name__ == '__main__':
q = multiprocessing.Queue()
processes = [multiprocessing.Process(target=worker, args=(q,)) for _ in range(4)]
for process in processes:
process.start()
for i in range(10):
q.put(i)
for _ in range(len(processes)):
q.put(None)
for process in processes:
process.join()
2.4 套接字
使用 Python 的 socket 模块可以创建套接字,进而实现网络通信和进程间通信。下面是一个简单的例子,创建了一个服务器进程和一个客户端进程。服务器进程监听本机的 8888 端口,接收客户端发来的数据并打印出来;客户端进程连接服务器的 8888 端口,并向服务器发送一条消息。运行上述代码后,可以看到服务器进程收到客户端发送的消息并打印出来:
import socket
def server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('127.0.0.1', 8888))
server_socket.listen(1)
conn, addr = server_socket.accept()
while True:
data = conn.recv(1024)
if not data:
break
print(data.decode())
conn.close()
server_socket.close()
def client():
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('127.0.0.1', 8888))
client_socket.sendall(b'Hello, server')
client_socket.close()
if __name__ == '__main__':
import multiprocessing
server_process = multiprocessing.Process(target=server)
client_process = multiprocessing.Process(target=client)
server_process.start()
client_process.start()
server_process.join()
client_process.join()
2.5 文件
在 Python 中使用文件进行进程间通信也是比较常见的方式。下面是一个例子,创建了一个文件 test.txt,该文件包含了三行文本。然后启动两个进程去调用 worker 函数,该函数会读取文件内容并打印出来。当两个进程都完成任务后,主进程结束。运行上述代码后,可以看到两个进程分别打印了 test.txt 文件的内容:
import multiprocessing
def worker(file):
with open(file, 'r') as f:
for line in f:
print(line.rstrip())
if __name__ == '__main__':
filename = 'test.txt'
with open(filename, 'w') as f:
f.write('Line 1\n')
f.write('Line 2\n')
f.write('Line 3\n')
processes = [multiprocessing.Process(target=worker, args=(filename,)) for _ in range(2)]
for process in processes:
process.start()
for process in processes:
process.join()
三 python子进程传数据到主进程的方式
Python中有多种方式可以让子进程传递数据给主进程。这里我列举其中三种比较常用的方式:
使用队列(Queue):队列是多进程编程中常用的通信工具,可以在多个进程之间传递消息。在主进程中初始化一个队列对象,然后将其作为参数传递给子进程,在子进程中使用put()方法向队列中添加数据,主进程可以使用get()方法获取数据。
下面是一个使用队列实现子进程传递数据给主进程的例子:
import multiprocessing as mp
def func(queue):
# 子进程向队列中添加数据
queue.put("hello from child process")
if __name__ == '__main__':
# 初始化一个队列
queue = mp.Queue()
# 创建一个子进程并将队列作为参数传递给它
p = mp.Process(target=func, args=(queue,))
p.start()
# 主进程从队列中获取数据
data = queue.get()
print(data)
使用管道(Pipe):管道也可以在多个进程之间传递消息,不同于队列的是它只支持两个进程之间的通信。在主进程中创建一个管道,然后将其作为参数传递给子进程,在子进程中使用send()方法向管道中发送数据,主进程可以使用recv()方法接收数据。
下面是一个使用管道实现子进程传递数据给主进程的例子:
import multiprocessing as mp
def func(pipe):
# 子进程向管道中发送数据
pipe.send("hello from child process")
if __name__ == '__main__':
# 创建一个管道
parent_conn, child_conn = mp.Pipe()
# 创建一个子进程并将管道作为参数传递给它
p = mp.Process(target=func, args=(child_conn,))
p.start()
# 主进程从管道中接收数据
data = parent_conn.recv()
print(data)
使用共享内存(Value和Array):共享内存可以让多个进程之间共享同一块内存区域,这样就可以避免进程之间频繁地复制数据。在主进程中使用Value或Array创建一个共享内存对象,然后将其作为参数传递给子进程,在子进程中可以直接修改共享内存对象中的值,主进程也可以直接读取共享内存对象中的值。
下面是一个使用共享内存实现子进程传递数据给主进程的例子:
import multiprocessing as mp
def func(val):
# 子进程修改共享内存对象中的值
val.value = 123
if __name__ == '__main__':
# 创建一个共享内存对象
val = mp.Value('i', 0)
# 创建一个子进程并将共享内存对象作为参数传递给它
p = mp.Process(target=func, args=(val,))
p.start()
# 主进程读取共享内存对象中的值
print(val.value)
来源:https://blog.csdn.net/March_A/article/details/130959349
猜你喜欢
- 本文实例讲述了Python基于辗转相除法求解最大公约数的方法。分享给大家供大家参考,具体如下:之前总结过一次高德纳TAOCP中的最大公约数求
- exec sp_configure 'show advanced options',1 reconfigure exec s
- 概述我一直在找一种好的方法来解释 go 语言的并发模型:不要通过共享内存来通信,相反,应该通过通信来共享内存但是没有发现一个好的解释来满足我
- 跨域问题一直是前端中常见的问题,每当说到跨域,第一浮现的技术必然就是JSONPJSONP在我的理解,它并不是ajax,它是在文档中插入一个s
- 今天呢,田辛老师来给大家继续讲一个著名的项目管理工具:蒙特卡洛模拟。 当然,田辛老师既然发到CSDN上面,无论如何要给出关于蒙特卡洛模拟的P
- 本文实例讲述了Python常见数据类型转换操作。分享给大家供大家参考,具体如下:类型转换主要针对几种存储工具:list、tuple、dict
- iniconf博主前两天在写一个小的go语言项目,想找一个读取ini格式配置和的三方库,在网上找了一圈感觉都不是很好用, 使用起来非常的奇怪
- 译序:本文译自Smashingmagazine,但是原文讲述的内容有些浅,也不是很完整,前端观察在翻译的前提下,增加了更多的更系统的内容。如
- Flask的模板功能是基于Jinja2模板引擎来实现的。模板文件存放在当前目前下的子目录templates(一定要使用这个名字)下。main
- !!!本博客,是对图像的背景颜色的修改的基础讲解~!!!还包括一个练习——是对背景色修改的一点应用尝试!!!——始终相信学习多一点探索,脚步
- 背景:我们有一个用go做的项目,其中用到了zmq4进行通信,一个简单的rpc过程,早期远端是使用一个map去做ip和具体socket的映射。
- 五、过渡转化的使用在《mind hack》一书中,揭示了人脑鲜为人知的工作原理。其中提到了“突然的移动或闪烁会吸引人的注意力,这正是负责视觉
- 废话不多了,直接贴代码了一查询数值型数据:SELECT * FROM tb_name WHERE sum > 100; 查询
- 前言本人做SSM项目的时候,在做删除功能时,发现找不到字段,在搜索了各种博客之后终于找到了解决办法一、报错Unknown column &a
- 本文实例为大家分享了Python画圣诞树的具体代码,供大家参考,具体内容如下源代码from turtle import *import ra
- __str__函数如果定义了该函数,当print当前实例化对象的时候,会返回该函数的return信息可用于定义当前类的描述信息用法:def
- 实例如下:function getQueStr(url, ref) //取获参数值{ var str = url.substr(
- 编码规范Python 编码规范重要性的原因用一句话来概括就是:统一的编码规范可以提高开发效率。无论你是 编程者,还是 阅读者,好的规范能让你
- 本文实例讲述了Python排序搜索基本算法之冒泡排序。分享给大家供大家参考,具体如下:冒泡排序和选择排序类似,也是第n次把最小的元素排在第n
- 昨天下班后忽然兴起想写一个爬虫抓抓网页上的东西。花了一个钟简单学习了python的基础语法,然后参照网上的例子自己写了个爬虫。python数