Python3 多进程共享变量实现方法(亲测) |
您所在的位置:网站首页 › python数据共享 › Python3 多进程共享变量实现方法(亲测) |
一、错误的实现方式
最初以为是没添加global声明导致修改未生效,但实际操作发现global方式在多进程中也只能读不能写。错误示例代码如下: import multiprocessing # 声明一个全局变量 share_var = ["start flag"] def sub_process(process_name): # 企图像单个进程那样通过global声明使用全局变量 global share_var share_var.append(process_name) # 但是很可惜,在多进程中这样引用只能读,修改其他进程不会同步改变 for item in share_var: print(f"{process_name}-{item}") pass def main_process(): process_list = [] # 创建进程1 process_name = "process 1" tmp_process = multiprocessing.Process(target=sub_process,args=(process_name,)) process_list.append(tmp_process) # 创建进程2 process_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先执行): 执行结果如下,可以看到进程1中的修改已表现在进程2中(不过要注意,和多线程一样,如果运算量再大一点进程1并不一定比进程2先执行): typecode如果是数值或单个字符,可为以下类型(注意有引号): Type CodeC TypePython Type'c'charcharacter'b'signed charint'B'unsigned charint'u'Py_UNICODEunicode character'h'signed shortint'H'unsigned shortint'i'signed intint'I'unsigned intint'l'signed longint'L'unsigned longint'f'floatfloat'd'doubleflo如果是字符串类型,typecode可为以下第一列形式(注意无引号): ctypes typeC typePython typec_bool _Boolbool (1)char char1-character stringc_wcharwchar_t1-character unicode stringc_bytecharint/longc_ubyteunsigned charint/longc_shortshortint/longc_ushortunsigned shortint/longc_intintint/longc_uintunsigned inint/longc_longlongint/longc_ulongunsigned longint/longc_longlong__int64 or long longint/longc_ulonglongunsigned __int64 or unsigned long longint/longc_floatfloatfloatc_doubledoublefloatc_longdoublelong doublefloatc_char_pchar * (NUL terminated)string or Nonec_wchar_p wchar_t * (NUL terminated)unicode or Nonec_void_pvoid *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_lock share_lock.acquire() file_obj.writelines(f"{process_name}") share_lock.release() pass def main_process(): process_list = [] # 创建进程1 process_name = "process 1" tmp_process = multiprocessing.Process(target=sub_process,args=(process_name,)) process_list.append(tmp_process) # 创建进程2 process_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 共享需要修改实例化对象实现方法----使用BaseManagerglobal方式不能修改变量(如要修改其成员变量),在大多时候也是可以了,但总让人觉得不是一种完美的实现方法。有没有可以修改的实现方法呢,答案是有的,可以使用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_lock share_lock.acquire() obj.test_function(f"{process_name}") share_lock.release() obj.print_test_list() pass def 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 = [] # 创建进程1 process_name = "process 1" tmp_process = multiprocessing.Process(target=sub_process,args=(process_name,obj)) process_list.append(tmp_process) # 创建进程2 process_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先执行): |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |