今天同事反映一个问题让帮忙看一下:多进程共用一个变量,在一个进程中修改后,在另外的进程中并没有产生修改。

一、错误的实现方式

最初以为是没添加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 多进程共享变量实现方法相关推荐

  1. Python3 多进程共享变量实现方法(亲测)

    一.错误的实现方式 最初以为是没添加global声明导致修改未生效,但实际操作发现global方式在多进程中也只能读不能写.错误示例代码如下: import multiprocessing# 声明一个 ...

  2. c 语言 多进程,VC++中进程与多进程管理的方法详解

    本文实例讲述了VC++中进程与多进程管理的方法,分享给大家供大家参考.具体方法分析如下: 摘要: 本文主要介绍了多任务管理中的多进程管理技术,对进程的互斥运行.子进程的创建与结束等作了较详细的阐述. ...

  3. python 共享内存变量_浅谈python多进程共享变量Value的使用tips

    前言: 在使用tornado的多进程时,需要多个进程共享一个状态变量,于是考虑使用multiprocessing.Value(对于该变量的具体细节请查阅相关资料).在根据网上资料使用Value时,由于 ...

  4. VC++中进程与多进程管理的方法[转]

    VC++中进程与多进程管理的方法      关键词: VC++6.0:进程:环境变量:子进程 进程 进程是当前操作系统下一个被加载到内存的.正在运行的应用程序的实例.每一个进程都是由内核对象和地址空间 ...

  5. 【python】多进程共享变量

    有一个字典变量,需要在多个进程间共享 使用Manager, 下面是一个小例子. 注意使用json前需要将类型转换. #!/usr/bin/python # coding=utf-8import jso ...

  6. python基础30个常用代码大全-Python3列表内置方法大全及示例代码小结

    Python中的列表是简直可说是有容乃大,虽然看似类似C中的数组,但是Python列表可以接受任意的对象元素,比如,字符串,数字,布尔值,甚至列表,字典等等,自由度提升到一个新的高度,而Python也 ...

  7. Python 多进程异常处理的方法,你会吗

    最近项目用到了Python作为网站的前端,使用的框架是基于线程池的Cherrypy,但是前端依然有一些比较'重'的模块.由于python的多线程无法很好的利用多核的性质,所以觉得把这些比较'重'的功能 ...

  8. python多进程的使用方法

    多进程的使用方法,如图所示: p = pool.Pool()process_num = 10 divide = 1/process_numfor i in range(process_num):p.a ...

  9. python默认安装地址_python多版本下设置python3为默认的方法

    python3设置为多版本为默认的方法 如何在双python下设置python3为默认 在C:\Program下举例 第一步安装好python2和python3后设置好环境变量 第二步去掉python ...

最新文章

  1. android横竖屏切换生命周期
  2. MySQL 子查询 嵌套查询
  3. h5页面点击事件ios没反应 移动端兼容性问题
  4. python全栈计划_Python 全栈学习视频教程,包含了从 0-99天的全栈学习计划,估计可以学习 1024 小时。...
  5. Sun HotSpot JVM内存管理及垃圾收集
  6. hdfs-大数据Week6-DAY2-2-hdfs
  7. 联想服务器怎么备份系统软件,联想笔记本通过命令进行系统备份的教程
  8. 【数据结构】图的存储结构—邻接矩阵
  9. 做了一个iGoogle新闻Gardget
  10. 【书评】《你好哇,程序员——漫话程序员面试求职、升职加薪、创业与生活》
  11. 骁龙660是32位还是64位_高通骁龙手机cpu64位比32位有什么优势?
  12. php socket 模拟http请求
  13. 14种方式,34个案例:对比SQL,学习Pandas操作
  14. 简单几步就可以把pdf转换成excel格式
  15. web调试工具使用fiddler
  16. 选择软件测试你后悔吗?
  17. C# 完美解决窗体切换闪屏问题
  18. 捷俊通称重软件教你如何处理简单地磅软件故障
  19. 机器的虚拟调试 - MapleSim Insight 对高空作业车稳定性进行实时调试
  20. sharepoint2010 list联合查询--(未整理)

热门文章

  1. 云原生思想 — 云原生的 DevOps
  2. 网络性能测试工具iperf的使用与参数解析
  3. JavaScript算法题:查找数字在数组中的索引
  4. 在RHEL5下构建DHCP及DHCP中继服务器
  5. main函数带参数C程序设计模板
  6. 九眼智能:信息安全是网络发展的关键
  7. 算法面试:精选微软经典的算法面试100题(第1-20题)
  8. 教你学习快速排序算法-程序员必备哦
  9. Fastjson的基本使用方法大全
  10. 二维几何变换---OpenGL几何变换编程示例