python多任务04-进程间不共享全局变量

1 访问全局变量

既然我们可以通过多进程的方式同时执行多个方法,那如果每个方法都对全局变量进行了访问(比如读写操作),那进程访问到的全局变量是同一个吗?答案是:不是同一个全局变量。

下面通过一个例子来具体解释:
在此我们定义一个全局列表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 2522121484360

2 打印方法地址

我们也可以在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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值