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方式在多进程中也只能读不能写.错误示例代码如下: import multiprocessing# 声明一个 ...
- c 语言 多进程,VC++中进程与多进程管理的方法详解
本文实例讲述了VC++中进程与多进程管理的方法,分享给大家供大家参考.具体方法分析如下: 摘要: 本文主要介绍了多任务管理中的多进程管理技术,对进程的互斥运行.子进程的创建与结束等作了较详细的阐述. ...
- python 共享内存变量_浅谈python多进程共享变量Value的使用tips
前言: 在使用tornado的多进程时,需要多个进程共享一个状态变量,于是考虑使用multiprocessing.Value(对于该变量的具体细节请查阅相关资料).在根据网上资料使用Value时,由于 ...
- VC++中进程与多进程管理的方法[转]
VC++中进程与多进程管理的方法 关键词: VC++6.0:进程:环境变量:子进程 进程 进程是当前操作系统下一个被加载到内存的.正在运行的应用程序的实例.每一个进程都是由内核对象和地址空间 ...
- 【python】多进程共享变量
有一个字典变量,需要在多个进程间共享 使用Manager, 下面是一个小例子. 注意使用json前需要将类型转换. #!/usr/bin/python # coding=utf-8import jso ...
- python基础30个常用代码大全-Python3列表内置方法大全及示例代码小结
Python中的列表是简直可说是有容乃大,虽然看似类似C中的数组,但是Python列表可以接受任意的对象元素,比如,字符串,数字,布尔值,甚至列表,字典等等,自由度提升到一个新的高度,而Python也 ...
- Python 多进程异常处理的方法,你会吗
最近项目用到了Python作为网站的前端,使用的框架是基于线程池的Cherrypy,但是前端依然有一些比较'重'的模块.由于python的多线程无法很好的利用多核的性质,所以觉得把这些比较'重'的功能 ...
- python多进程的使用方法
多进程的使用方法,如图所示: p = pool.Pool()process_num = 10 divide = 1/process_numfor i in range(process_num):p.a ...
- python默认安装地址_python多版本下设置python3为默认的方法
python3设置为多版本为默认的方法 如何在双python下设置python3为默认 在C:\Program下举例 第一步安装好python2和python3后设置好环境变量 第二步去掉python ...
最新文章
- android横竖屏切换生命周期
- MySQL 子查询 嵌套查询
- h5页面点击事件ios没反应 移动端兼容性问题
- python全栈计划_Python 全栈学习视频教程,包含了从 0-99天的全栈学习计划,估计可以学习 1024 小时。...
- Sun HotSpot JVM内存管理及垃圾收集
- hdfs-大数据Week6-DAY2-2-hdfs
- 联想服务器怎么备份系统软件,联想笔记本通过命令进行系统备份的教程
- 【数据结构】图的存储结构—邻接矩阵
- 做了一个iGoogle新闻Gardget
- 【书评】《你好哇,程序员——漫话程序员面试求职、升职加薪、创业与生活》
- 骁龙660是32位还是64位_高通骁龙手机cpu64位比32位有什么优势?
- php socket 模拟http请求
- 14种方式,34个案例:对比SQL,学习Pandas操作
- 简单几步就可以把pdf转换成excel格式
- web调试工具使用fiddler
- 选择软件测试你后悔吗?
- C# 完美解决窗体切换闪屏问题
- 捷俊通称重软件教你如何处理简单地磅软件故障
- 机器的虚拟调试 - MapleSim Insight 对高空作业车稳定性进行实时调试
- sharepoint2010 list联合查询--(未整理)