python 主进程中的全局变量在多个进程中不共享

全局变量在多个进程中不共享:
进程之间的数据是独立的,默认情况下互不影响

原理是创建子进程是会将主进程的资源copy一份给子进程,子进程拥有一份与主进程一样的代码,子进程会将这代码在执行一遍。但是if__name__=='__main__':内部的代码就不会执行了。

由于进程之间的数据是独立的。主进程中的全局变量,在进程中也复制了一份,他们名字一样,其实并不是同一个。

import multiprocessing
import os

#主进程中定义全局变量
print('------------------' + '进程%s' % multiprocessing.current_process().name)
num = [99,100]
print(id(num))
print('------------------' + '进程%s' % multiprocessing.current_process().name)

def work1():
    print('------------------' + '进程%s' % multiprocessing.current_process().name)
    print("work1正在运行......")
    print(id(num))
    print('------------------' + '进程%s' % multiprocessing.current_process().name)
    print('\n')

def work2():
    print('------------------' + '进程%s' % multiprocessing.current_process().name)
    print("work2正在运行......")
    print(id(num))
    print('------------------' + '进程%s' % multiprocessing.current_process().name)
    print('\n')


if __name__ == '__main__':
    print('主进程.......................')
    print("主进程中的num的id %s"%id(num))
    print('\n')

    p1 = multiprocessing.Process(target=work1)
    p1.start()
    p1.join()

    p2 = multiprocessing.Process(target=work2)
    p2.start()
    p2.join()

    print('主进程结束了....................')

最上面的代码,写在main之外的:
这部分语句,子进程也会执行,因为子进程创建时,会copy一份主进程的代码,包括后面的函数定义都会执行一遍,main内部的自然不会了

print('------------------' + '进程%s' % multiprocessing.current_process().name)
num = [99,100]
print(id(num))
print('------------------' + '进程%s' % multiprocessing.current_process().name)

所以这部分代码会被主进程,子进程1,子进程2分别执行一次,根据每次输出的id(num),我们就可以发现,两个子进程内部也会再次创建一次叫做num的变量,同时num指向的是一个可变类型,再次创建的时候就会重新申请内存,所以id(num)是不一样的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上面每部分结果对应着的代码,可以看到的是主进程,子进程1,子进程2中输出的id(num)是分别不同的,而且每个进程也确实的执行了这部分代码

#主进程中定义全局变量
print('------------------' + '进程%s' % multiprocessing.current_process().name)
num = [99,100]
print(id(num))
print('------------------' + '进程%s' % multiprocessing.current_process().name)

同时每个进程的内部,输出的id(num)是一样的,如下图:
在这里插入图片描述
就是说,每个子进程内部都有一个叫num的变量,不同进程的num指向的地址是不一样的。所以子进程内部使用的这个num,其实就是子进程自己的,主进程的num你是拿不到的,因为进程之间是独立的。
代码修改一下:

#主进程中定义全局变量
print('------------------' + '进程%s' % multiprocessing.current_process().name)
num = [99,100]
print(id(num))
print('------------------' + '进程%s' % multiprocessing.current_process().name)

def work1():
    print('------------------' + '进程%s' % multiprocessing.current_process().name)
    print("work1正在运行......")
    print(id(num))
    num.append(101)
    print(num)
    print('------------------' + '进程%s' % multiprocessing.current_process().name)
    print('\n')

def work2():
    print('------------------' + '进程%s' % multiprocessing.current_process().name)
    print("work2正在运行......")
    print(id(num))
    num.append(102)
    print(num)
    print('------------------' + '进程%s' % multiprocessing.current_process().name)
    print('\n')


if __name__ == '__main__':
    print('主进程.......................')
    print("主进程中的num的id %s"%id(num))
    print('\n')

    p1 = multiprocessing.Process(target=work1)
    p1.start()
    p1.join()

    p2 = multiprocessing.Process(target=work2)
    p2.start()
    p2.join()
    print('进程结束了')

    print("主进程中的num是%s"%num)
    print('主进程结束了....................')

在这里插入图片描述
在这里插入图片描述
可以看出子进程是修改不了主进程中的全局变量的。

如果num是不可变类型

代码为:

# 主进程中定义全局变量
print('------------------' + '进程%s' % multiprocessing.current_process().name)
num = 99
print(id(num))
print('------------------' + '进程%s' % multiprocessing.current_process().name)


def work1():
    print('------------------' + '进程%s' % multiprocessing.current_process().name)
    print("work1正在运行......")
    global num	#声明使用外面的num
    print(id(num))
    num  = 100	
    print(id(num))	#修改后在输出一下id
    print('------------------' + '进程%s' % multiprocessing.current_process().name)
    print('\n')

def work2():
    print('------------------' + '进程%s' % multiprocessing.current_process().name)
    print("work2正在运行......")
    print(id(num))
    print('------------------' + '进程%s' % multiprocessing.current_process().name)
    print('\n')


if __name__ == '__main__':
    print('主进程.......................')
    print("主进程中的num的id %s"%id(num))
    print('\n')

    p1 = multiprocessing.Process(target=work1)
    p1.start()
    p1.join()

    p2 = multiprocessing.Process(target=work2)
    p2.start()
    p2.join()

    print("主进程中的num的id %s" % id(num))
    print('主进程结束了....................')

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
由于num现在指向的是不可变对象,同时是python中的小整数对象,拥有固定的内存,所以不论是主进程还是子进程,id(num)的结果是一样的。

在子进程1中声明使用的外部num,并不是主进程中的num ,而是子进程1中的num,因为子进程1会copy主进程的代码,上面那部分一执行,子进程1就有了自己的num,使用的时候就使用了自己的num,而且进程是独立的,你也访问不到主进程中的num。

所以总体来说,主进程中的全局变量,子进程中会有一份一模一样的,子进程中访问和修改的其实都是自己的变量,只是和主进程中的那个变量名字一样。子进程不能修改到主进程中的全局变量,因为进程之间是独立的。

这是我目前的理解,不能保证准确。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值