一、错误的实现方式

最初以为是没添加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 ...

  2. windows 2003 远程桌面无法使用剪贴板共享纯文本的解决方法(亲测可用)

    windows 2003 远程桌面无法使用剪贴板共享纯文本的解决方法(亲测可用) 参考文章: (1)windows 2003 远程桌面无法使用剪贴板共享纯文本的解决方法(亲测可用) (2)https: ...

  3. 微信开发者解除绑定微信公众号的方法,亲测有效

    微信开发者解除绑定微信公众号的方法,亲测有效 微信关注 '公众平台安全助手' 点击'绑定查询',选择'微信号绑定账号',出现以下页面: 点击列表右边的箭头 ,选择'解除绑定'即可: 这个问题相信对很多 ...

  4. 电视android已停止运行是什么意思,智能电视提示应用停止运行,三种方法亲测有效!...

    原标题:智能电视提示应用停止运行,三种方法亲测有效! 智能电视使用时间一长,或者是使用不当总会出现一些问题,当电视机页面出现"某软件"已经停止运行提示的时候,是什么原因导致的?自己 ...

  5. 笔记本识别不出来U盘的解决方法 [亲测有效]

    笔记本识别不出来U盘的解决方法 [亲测有效] 转载连接https://jingyan.baidu.com/album/f96699bbfa1491894e3c1bc3.html?picindex=4 ...

  6. 为Android购买多个改装微信,分享外面高价售卖的修改微信号方法 亲测成功 仅限安卓手机...

    分享外面在高价售卖的微信号修改方法 亲测成功 仅限安卓手机 这个方法今天在外面看到很多人在代修改,转卖方法!小编觉得还是有必要发出来让大家去动手尝试一下! 实际上这个修改微信号的功能在内测版微信就可以 ...

  7. Python3飞机大战全代码(亲测OJBK)

    以下是亲测Python飞机大战全部代码,在保证有pygame环境支持并且有Python3解释器的话完全没问题! 如果大家喜欢的话麻烦点个赞! 当然没有图片的可以给小编评论留下自己的qq号并且点个赞,晚 ...

  8. 网上的音乐怎么下载成mp3格式歌曲?这3种一键下载的方法亲测好用!

    网易云音乐客户端是支持直接下载音乐的,但是有时候是加密格式,今天就教大家3个直接网页下载mp3格式音乐的方法,下载之后直接就能播放,亲测好用! 方法一:审查元素下载 一个简单有效的下载方法,不需要使用 ...

  9. Ubuntu连接不了网络的解决方法亲测可行经验

    突然发现Ubuntu连不上网络,网络打问号或者右上角也没有网络图标:楼主一般通过前两步就解决了,大家自行查阅网络服务名称,OK直接进入正题 通过命令行方式重启网络 如果你使用的 Ubuntu 服务器版 ...

最新文章

  1. [转]ubuntu linux下DNS重启后丢失(不是Network-manager造成的情况)
  2. can't find a register in class `GENERAL_REGS' while reloading `asm'
  3. linux 编译内核几个常见问题解决方法
  4. 面型对象 (包package)
  5. 2019年1月16日【第三天学习】
  6. Number Sequence (KMP的应用)
  7. 信息学奥赛一本通(2050:【例5.20】字串包含)
  8. 使用haskell来解线性方程
  9. mysql安装 demo [linux centos7] [5.7.26]
  10. VirtualBox启动报错
  11. bootstrap表格插件php,深入了解Bootstrap table表格插件(一)
  12. VDI序曲十一 微软桌面虚拟化之授权服务器
  13. java桥梁模式_java设计模式之桥梁模式(Bridge)
  14. python中unique函数_Pandas Series.unique()用法介绍
  15. 实战Python轻松实现绘制词云图(附详细源码)
  16. 360桌面整理计算机图标,电脑桌面脏乱差 360桌面助手一键整理
  17. 学习笔记96—WIN7/WIN8/WIN10 安装 MSDE SQL2000 卡住不动的解决办法
  18. java-贪吃蛇小游戏
  19. 博客总纲 博客目录V1
  20. manjaro Linux 手动安装mysql 5.7 每次重启系统都无法直接启动

热门文章

  1. 金字塔原理只需读前几页
  2. 《细胞》重磅成果!任兵课题组绘制迄今最大规模人类单细胞染色质可及性图谱...
  3. 推荐一个在线全自动智能图片背景扣除工具,效果杠杠的
  4. 那个一年发四篇Cell的研究生,后来怎么样了?
  5. AutoCAD 2021 macOS Big Sur 11版 注册机无法打开?注册机怎么使用?
  6. 【docker】第五节:docker常用命令总结
  7. 德芙网络营销策略ppt_德芙网络营销方案
  8. python解析html xml最好的模块_python中处理xml的模块哪个好?
  9. c语言用递归方法实现冒泡排序,C语言 冒泡排序 递归法
  10. Spring Boot文档阅读笔记-构建Restful风格的WebService客户端