Python3 多进程共享变量实现方法(亲测)
一、错误的实现方式
最初以为是没添加global声明导致修改未生效,但实际操作发现global方式在多进程中也只能读不能写。错误示例代码如下:
import multiprocessing# 声明一个全局变量
share_var = ["start flag"]def sub_process(process_name):# 企图像单个进程那样通过global声明使用全局变量global share_varshare_var.append(process_name)# 但是很可惜,在多进程中这样引用只能读,修改其他进程不会同步改变for item in share_var:print(f"{process_name}-{item}")passdef main_process():process_list = []# 创建进程1process_name = "process 1"tmp_process = multiprocessing.Process(target=sub_process,args=(process_name,))process_list.append(tmp_process)# 创建进程2process_name = "process 2"tmp_process = multiprocessing.Process(target=sub_process, args=(process_name,))process_list.append(tmp_process)# 启动所有进程for process in process_list:process.start()for process in process_list:process.join()if __name__ == "__main__":main_process()
执行结果如下,可以看到进程1中的修改未表现在进程2中(不过要注意,和多线程一样,如果运算量再大一点进程1并不一定比进程2先执行):
二、共享普通类型变量实现方法
import multiprocessing# 不能将共享变量和共享锁定义成全局变量然后通过global引用那样会报错,只能传过来
def sub_process(process_name,share_var,share_lock):# 获取锁share_lock.acquire()share_var.append(process_name)# 释放锁share_lock.release()for item in share_var:print(f"{process_name}-{item}")passdef main_process():# 单个值声明方式。typecode是进制类型,value是初始值# share_var = multiprocessing.Manager().Value(typecode, value)# 数组声明方式。typecode是数组变量中的变量类型,sequence是数组初始值# share_var = multiprocessing.Manager().Array(typecode, sequence)# 字典声明方式# share_var = multiprocessing.Manager().dict()# 列表声明方式share_var = multiprocessing.Manager().list()share_var.append("start flag")# 声明一个共享锁share_lock = multiprocessing.Manager().Lock()process_list = []process_name = "process 1"tmp_process = multiprocessing.Process(target=sub_process,args=(process_name,share_var,share_lock))process_list.append(tmp_process)process_name = "process 2"tmp_process = multiprocessing.Process(target=sub_process, args=(process_name,share_var,share_lock))process_list.append(tmp_process)for process in process_list:process.start()for process in process_list:process.join()if __name__ == "__main__":main_process()
执行结果如下,可以看到进程1中的修改已表现在进程2中(不过要注意,和多线程一样,如果运算量再大一点进程1并不一定比进程2先执行):
typecode如果是数值或单个字符,可为以下类型(注意有引号):
Type Code | C Type | Python Type |
'c' | char | character |
'b' | signed char | int |
'B' | unsigned char | int |
'u' | Py_UNICODE | unicode character |
'h' | signed short | int |
'H' | unsigned short | int |
'i' | signed int | int |
'I' | unsigned int | int |
'l' | signed long | int |
'L' | unsigned long | int |
'f' | float | float |
'd' | double | flo |
如果是字符串类型,typecode可为以下第一列形式(注意无引号):
ctypes type | C type | Python type |
c_bool |
_Bool | bool (1) |
char | char | 1-character string |
c_wchar | wchar_t | 1-character unicode string |
c_byte | char | int/long |
c_ubyte | unsigned char | int/long |
c_short | short | int/long |
c_ushort | unsigned short | int/long |
c_int | int | int/long |
c_uint | unsigned in | int/long |
c_long | long | int/long |
c_ulong | unsigned long | int/long |
c_longlong | __int64 or long long | int/long |
c_ulonglong | unsigned __int64 or unsigned long long | int/long |
c_float | float | float |
c_double | double | float |
c_longdouble | long double | float |
c_char_p | char * (NUL terminated) | string or None |
c_wchar_p |
wchar_t * (NUL terminated) | unicode or None |
c_void_p | void * | int/long or None |
三、共享实例化对象实现方法
同事还想共享一个文件对象,然后问上边的方法是不是只能共享字典、列表,没法共享对象。
回头一看,Value和Array中typecode要求是c语言中存在的类型,其他只有dict()和list()方法没有其他方法,所以似乎上边的方法共享实例化对象是不行的。
import multiprocessing
import threading# 实例化一个全局文件对象
file_obj = open("1.txt","a")
share_lock = threading.Lock()def sub_process(process_name):global file_obj,share_lockshare_lock.acquire()file_obj.writelines(f"{process_name}")share_lock.release()passdef main_process():process_list = []# 创建进程1process_name = "process 1"tmp_process = multiprocessing.Process(target=sub_process,args=(process_name,))process_list.append(tmp_process)# 创建进程2process_name = "process 2"tmp_process = multiprocessing.Process(target=sub_process, args=(process_name,))process_list.append(tmp_process)# 启动所有进程for process in process_list:process.start()for process in process_list:process.join()if __name__ == "__main__":main_process()
3.2 共享需要修改实例化对象实现方法----使用BaseManager
global方式不能修改变量(如要修改其成员变量),在大多时候也是可以了,但总让人觉得不是一种完美的实现方法。有没有可以修改的实现方法呢,答案是有的,可以使用BaseManager。示例代码如下。
import multiprocessing
from multiprocessing.managers import BaseManager
import threading# 锁可以通过global也可以在Process中传无所谓
share_lock = threading.Lock()# 定义一个要共享实例化对象的类
class Test():def __init__(self):self.test_list = ["start flag"]def test_function(self,arg):self.test_list.append(arg)def print_test_list(self):for item in self.test_list:print(f"{item}")def sub_process(process_name,obj):global share_lockshare_lock.acquire()obj.test_function(f"{process_name}")share_lock.release()obj.print_test_list()passdef main_process():# 如果是想注册open方法这样操作# manager = BaseManager()# # 一定要在start前注册,不然就注册无效# manager.register('open', open)# manager.start()# obj = manager.open("1.txt","a")# 为了更加直接我们直接以一个Test类的实例化对象来演示manager = BaseManager()# 一定要在start前注册,不然就注册无效manager.register('Test', Test)manager.start()obj = manager.Test()process_list = []# 创建进程1process_name = "process 1"tmp_process = multiprocessing.Process(target=sub_process,args=(process_name,obj))process_list.append(tmp_process)# 创建进程2process_name = "process 2"tmp_process = multiprocessing.Process(target=sub_process, args=(process_name,obj))process_list.append(tmp_process)# 启动所有进程for process in process_list:process.start()for process in process_list:process.join()if __name__ == "__main__":main_process()
执行结果如下,可以看到进程1中的修改已表现在进程2中(不过要注意,和多线程一样,如果运算量再大一点进程1并不一定比进程2先执行):
Python3 多进程共享变量实现方法(亲测)相关推荐
- python3 多进程共享变量实现方法
今天同事反映一个问题让帮忙看一下:多进程共用一个变量,在一个进程中修改后,在另外的进程中并没有产生修改. 一.错误的实现方式 最初以为是没添加global声明导致修改未生效,但实际操作发现global ...
- windows 2003 远程桌面无法使用剪贴板共享纯文本的解决方法(亲测可用)
windows 2003 远程桌面无法使用剪贴板共享纯文本的解决方法(亲测可用) 参考文章: (1)windows 2003 远程桌面无法使用剪贴板共享纯文本的解决方法(亲测可用) (2)https: ...
- 微信开发者解除绑定微信公众号的方法,亲测有效
微信开发者解除绑定微信公众号的方法,亲测有效 微信关注 '公众平台安全助手' 点击'绑定查询',选择'微信号绑定账号',出现以下页面: 点击列表右边的箭头 ,选择'解除绑定'即可: 这个问题相信对很多 ...
- 电视android已停止运行是什么意思,智能电视提示应用停止运行,三种方法亲测有效!...
原标题:智能电视提示应用停止运行,三种方法亲测有效! 智能电视使用时间一长,或者是使用不当总会出现一些问题,当电视机页面出现"某软件"已经停止运行提示的时候,是什么原因导致的?自己 ...
- 笔记本识别不出来U盘的解决方法 [亲测有效]
笔记本识别不出来U盘的解决方法 [亲测有效] 转载连接https://jingyan.baidu.com/album/f96699bbfa1491894e3c1bc3.html?picindex=4 ...
- 为Android购买多个改装微信,分享外面高价售卖的修改微信号方法 亲测成功 仅限安卓手机...
分享外面在高价售卖的微信号修改方法 亲测成功 仅限安卓手机 这个方法今天在外面看到很多人在代修改,转卖方法!小编觉得还是有必要发出来让大家去动手尝试一下! 实际上这个修改微信号的功能在内测版微信就可以 ...
- Python3飞机大战全代码(亲测OJBK)
以下是亲测Python飞机大战全部代码,在保证有pygame环境支持并且有Python3解释器的话完全没问题! 如果大家喜欢的话麻烦点个赞! 当然没有图片的可以给小编评论留下自己的qq号并且点个赞,晚 ...
- 网上的音乐怎么下载成mp3格式歌曲?这3种一键下载的方法亲测好用!
网易云音乐客户端是支持直接下载音乐的,但是有时候是加密格式,今天就教大家3个直接网页下载mp3格式音乐的方法,下载之后直接就能播放,亲测好用! 方法一:审查元素下载 一个简单有效的下载方法,不需要使用 ...
- Ubuntu连接不了网络的解决方法亲测可行经验
突然发现Ubuntu连不上网络,网络打问号或者右上角也没有网络图标:楼主一般通过前两步就解决了,大家自行查阅网络服务名称,OK直接进入正题 通过命令行方式重启网络 如果你使用的 Ubuntu 服务器版 ...
最新文章
- [转]ubuntu linux下DNS重启后丢失(不是Network-manager造成的情况)
- can't find a register in class `GENERAL_REGS' while reloading `asm'
- linux 编译内核几个常见问题解决方法
- 面型对象 (包package)
- 2019年1月16日【第三天学习】
- Number Sequence (KMP的应用)
- 信息学奥赛一本通(2050:【例5.20】字串包含)
- 使用haskell来解线性方程
- mysql安装 demo [linux centos7] [5.7.26]
- VirtualBox启动报错
- bootstrap表格插件php,深入了解Bootstrap table表格插件(一)
- VDI序曲十一 微软桌面虚拟化之授权服务器
- java桥梁模式_java设计模式之桥梁模式(Bridge)
- python中unique函数_Pandas Series.unique()用法介绍
- 实战Python轻松实现绘制词云图(附详细源码)
- 360桌面整理计算机图标,电脑桌面脏乱差 360桌面助手一键整理
- 学习笔记96—WIN7/WIN8/WIN10 安装 MSDE SQL2000 卡住不动的解决办法
- java-贪吃蛇小游戏
- 博客总纲 博客目录V1
- manjaro Linux 手动安装mysql 5.7 每次重启系统都无法直接启动
热门文章
- 金字塔原理只需读前几页
- 《细胞》重磅成果!任兵课题组绘制迄今最大规模人类单细胞染色质可及性图谱...
- 推荐一个在线全自动智能图片背景扣除工具,效果杠杠的
- 那个一年发四篇Cell的研究生,后来怎么样了?
- AutoCAD 2021 macOS Big Sur 11版 注册机无法打开?注册机怎么使用?
- 【docker】第五节:docker常用命令总结
- 德芙网络营销策略ppt_德芙网络营销方案
- python解析html xml最好的模块_python中处理xml的模块哪个好?
- c语言用递归方法实现冒泡排序,C语言 冒泡排序 递归法
- Spring Boot文档阅读笔记-构建Restful风格的WebService客户端