今天同事反映一个问题让帮忙看一下:多进程共用一个变量,在一个进程中修改后,在另外的进程中并没有产生修改。
最初以为是没添加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先执行):
参考:https://blog.csdn.net/houyanhua1/article/details/78244288
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}") pass def 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先执行):
同事还想共享一个文件对象,然后问上边的方法是不是只能共享字典、列表,没法共享对象。
回头一看,Value和Array中typecode要求是c语言中存在的类型,其他只有dict()和list()方法没有其他方法,所以似乎上边的方法共享实例化对象是不行的。
但我们前面说过global方式不可以修改,但读还是没问题的;所以对象引用还是可以使用global方式,要修改则暂时不知道有什么方法。
import multiprocessing # 实例化一个全局文件对象 file_obj = open("1.txt","a") def sub_process(process_name): global file_obj file_obj.writelines(f"{process_name}") 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()
原文:https://www.cnblogs.com/lsdb/p/10815319.html