- 1 访问全局变量
- 2 打印g_list地址
- 2 打印方法地址
既然我们可以通过多进程的方式同时执行多个方法,那如果每个方法都对全局变量进行了访问(比如读写 *** 作),那进程访问到的全局变量是同一个吗?答案是:不是同一个全局变量。
下面通过一个例子来具体解释:
在此我们定义一个全局列表g_list=[ ],用来存储数据。再定义两个方法分别对g_list进行多次的读写 *** 作,每次间隔0.2秒。下面我们将要创建两个进程来同时执行这两个方法,如果他们共享全局列表g_list,那随着读写 *** 作的交替进行,每次读取列表打印的结果应该会不同。
import multiprocessing import time #定义全局变量列表 g_list=[] #写入全局变量 def write_data(): for i in range(3): #没有对全局变量的值做修改(指向的对象地址不变),不需要global关键字 g_list.append(i) print('添加数据:{}'.format(i)) time.sleep(0.2) print('数据添加完成',g_list) #读取全局变量 def read_data(): for i in range(3): print('读取到g_list:',g_list) time.sleep(0.2)
在此创建进程。
if __name__=='__main__':#主进程 # 添加数据的子进程 add_process = multiprocessing.Process(target=write_data, name='read_data') # 读取数据的子进程 read_process = multiprocessing.Process(target=read_data, name='read_data') add_process.start() # 等写入 *** 作结束再进行读取 #add_process.join() read_process.start()
下面来看运行结果,可以发现,每次读取到的全局列表都是[ ],说明该列表一直为空,而每次数据的添加也在正常执行,在最后数据全部添加完对g_list打印中,又发现列表里已经存储了[0,1,2],这是什么情况呢。
添加数据:0 读取到g_list: [] 添加数据:1读取到g_list: [] 读取到g_list:添加数据:2 [] 数据添加完成 [0, 1, 2]
这是因为,创建子进程其实是对主进程资源的拷贝(也就是说子进程是主进程的副本),在创建add_process 进程时,该进程将对主进程中的方法和全局变量作一份拷贝,之后的所有处理都将在拷贝的变量中进行(有点像平行宇宙的概念…),所以说g_list在主进程中存在,在两个子进程中也分别拷贝了一份,一共3份(可以通过打印地址来判断是否是同一个g_list),互不干扰。我们也可以在主进程打印g_list列表,看看他是否发生了变化。
2 打印g_list地址下面我们分别在主进程和两个子进程中打印g_list的地址。
import multiprocessing import time #定义全局变量列表 g_list=[] #写入全局变量函数 def write_data(): print('g address in write',id(g_list)) #读取全局变量函数 def read_data(): print('g address in read',id(g_list)) #如果是主模块,则创建进程时不会拷贝以下代码 if __name__=='__main__':#主进程 print('g address in main',id(g_list)) add_process = multiprocessing.Process(target=write_data, name='read_data') # 读取数据的子进程 read_process = multiprocessing.Process(target=read_data, name='read_data') add_process.start() read_process.start()
可以看到三个g_list的地址各不相同,证明了g_list在子进程中被拷贝了两份。
g address in main 2159678752712 g address in read 2527471384584 g address in write 25221214843602 打印方法地址
我们也可以在write进程中打印read方法的地址,观察它是否与主进程中read方法的地址相同。
import multiprocessing import time #定义全局变量列表 g_list=[] #写入全局变量函数 def write_data(): print('read_data id in write',id(read_data)) #读取全局变量函数 def read_data(): pass #如果是主模块,则创建进程时不会拷贝以下代码 if __name__=='__main__':#主进程 print('read_data id in main',id(read_data)) add_process = multiprocessing.Process(target=write_data, name='read_data') # 读取数据的子进程 read_process = multiprocessing.Process(target=read_data, name='read_data') add_process.start() read_process.start()
可以发现地址不同,说面read方法也在子进程中被拷贝了。
read_data id in main 2159679745336 read_data id in write 2522121492808
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)