02- python进程中的数据交互(Windows系统)

news/2024/11/28 9:36:01/

要点:

  • multiprocessing 进程间信息交互


一 方法汇总

在 Python 进程中,有几种方法可以实现数据交互:

  1. 共享内存:这是一种用于进程间通信的高效方式。多个进程可以访问同一个共享内存区域,并在其中读取和写入数据。

  2. 管道(Pipe):这是一种用于进程间通信的基本方式。管道可以在两个进程之间传递数据。一个进程将数据写入管道,另一个进程从管道中读取数据。

  3. 队列(Queue):队列也是一种进程间通信的方式。一个进程将数据放入队列,另一个进程从队列中获取数据。

  4. 套接字(Socket):套接字是一种用于网络通信的方式,但它们也可以在同一台计算机上进行进程间通信。每个套接字都有一个唯一的地址,进程可以使用这个地址来发送和接收数据。

  5. 文件:进程可以使用文件作为数据交换的方式。一个进程将数据写入文件,另一个进程从文件中读取数据。

二 实际举例

2.1 共享内存

使用 multiprocessing.Value 可以创建进程间共享的变量,下面是一个例子,创建了一个类型为整数('i')的共享内存变量 value,然后启动 10 个进程去调用 func 函数,该函数会将 value 的值加 1。最后输出 value 的值,应该是 10:

import multiprocessingdef func(value):value.value += 1if __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 是子进程持有的端口。然后启动两个进程,分别调用 senderreceiver 函数sender 函数发送一条消息到管道中,receiver 函数从管道中接收消息并打印出来:

import multiprocessingdef 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 multiprocessingdef worker(q):while True:item = q.get()if item is None:breakprint(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 socketdef 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:breakprint(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 multiprocessingserver_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 multiprocessingdef 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 mpdef 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 mpdef 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 mpdef func(val):# 子进程修改共享内存对象中的值val.value = 123if __name__ == '__main__':# 创建一个共享内存对象val = mp.Value('i', 0)# 创建一个子进程并将共享内存对象作为参数传递给它p = mp.Process(target=func, args=(val,))p.start()# 主进程读取共享内存对象中的值print(val.value)


http://www.ppmy.cn/news/109793.html

相关文章

价值5000元以上的某马大数据全套视频【强烈推荐】

某马大数据 01、阶段一 Python大数据开发基础 01、第一章大数据介绍及开发环境 02、第二章 linux命令 03、第三章 MySQL数据库 04、第四章 excel的使用 05、第五章 kettle的使用 06、第六章 数据分析及可视化 07、第七章 大数据框架与数仓基础 08、第八章 数仓实战项目 …

函数(C语言程序设计)

目录 一、函数定义 二、函数调用 三、递归函数 四、局部变量和全局变量 一、函数定义 1、无参函数的定义 类型名 函数名() /*函数首部*/ { 函数体 } 或 类型名 函数名(void) /*函数首部*/ { 函数体 } void类型的函数不…

2023年数学建模:支持向量机在数学建模中的应用

2023年9月数学建模国赛期间提供ABCDE题思路加Matlab代码,专栏链接(赛前一个月恢复源码199,欢迎大家订阅):http://t.csdn.cn/Um9Zd 目录 引言 支持向量机原理 1. 数学原理 2. 核函数 MATLAB实现 数学建模案例 总结 引言 支持向量机(Support Vector Machine&a…

Linux 上安装 PostgreSQL——Ubuntu

打开 PostgreSQL 官网 PostgreSQL: The worlds most advanced open source database,点击菜单栏上的 Download ,可以看到这里包含了很多平台的安装包,包括 Linux、Windows、Mac OS等 。 Linux 我们可以看到支持 Ubuntu 和 Red Hat 等各个平台…

vue项目案例(Vue3)

本篇文章主要是,使用 vite 创建一个vue3 项目,实践 vie-router4 vuex4 结合 componsition API 的使用。目的是让未接触过 vue3 的同学快速上手。 一、vue3.0 创建项目 vue3 创建项目的时候有两种方式,第一种就是官方推荐的 vite 。另外一种就…

【C/C++】之内存管理(超详细练气篇)

个人主页:平行线也会相交💪 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【C之路】💌 本专栏旨在记录C的学习路线,望对大家有所帮助🙇‍ 希望我们一起努力、成长&…

[RUST/腐蚀]Windows-开服服务端下载以及配置

一、前置要求 1.SteamCMD:SteamCMD - Valve Developer Communityhttps://developer.valvesoftware.com/wiki/SteamCMD 2.通过SteamCMD下载RUST/腐蚀服务端。 二、SteamCMD 注意:所有目录均应避免出现中文。 1.建立SteamCMD文件夹,如 D:\st…

达梦数据库8安装教程

第一步:双击驱动 注意:如果双击显示没有驱动,则安装WinCDEmu软件。 第二步:双击setup.exe安装包 第三步:选择时区 第四步:验证key文件 因为我们是免费试用,所以没有key文件,直接下一…