zoukankan      html  css  js  c++  java
  • [python]mac/windows python2 多进程全局变量作用域疑问

    在mac和windows上相同的python脚本,跑出了不同的效果。

    就是我在main里面声明的变数,多进程执行,在windows无法访问,但mac却可以。

    被卡了好久,有点困惑,这里记录一下现象~~原因不知道......

    #!/usr/bin/python
    #-*- coding: utf-8
    
    def getVar(temp2):
        print("temp var221 :%s"%temp2)
        global temp1 
        print("temp var111 :%s"%temp1)
        temp1 = "xiaoqiang3"
        print("temp var222 :%s"%temp1)
        print("temp var223 :%s"%temp2)
    
    if __name__ == '__main__':
        temp1 = "xiaoqiang"
        print("temp var1 before:%s"%temp1)
        getVar(temp1)
        print("temp var1 after:%s"%temp1)
    
    '''
    输出如下:
    temp var1 before:xiaoqiang
    temp var221 :xiaoqiang
    temp var111 :xiaoqiang
    temp var222 :xiaoqiang3
    temp var223 :xiaoqiang
    temp var1 after:xiaoqiang3
    '''
    

    全局变量不需要global声明,函数内的局部变量不会因为传入的变量改变而改变

    如果你需要获取并更改全局变量的值,需要在更改的地方,也就是函数内部,声明global属性,即可修改(不声明不会报错,但是打印的时候会报变量没有被引用,并且此时对象为函数内的局部变量,修改后的值无法作用到外部的全局变量)。

    想看一下内存地址的变化,于是打印了一下地址:

    #!/usr/bin/python
    #-*- coding: utf-8
    def getVar(temp2):
        print("temp var2 : %s value: %s"%(id(temp2),temp2)) #140611843258912
        global temp1
        print("temp var21 : %s value: %s"%(id(temp1),temp1)) #140611843258912
        temp1 = "xiaoqiang3"
        print("temp var11 : %s value: %s"%(id(temp1),temp1)) #140611843258768
        print("temp var22 : %s value: %s"%(id(temp2),temp2)) #140611843258912
    
        temp2 = "XiaoQQ"
        print("temp var33  : %s value: %s"%(id(temp2),temp2)) #140611843258816
    
    if __name__ == '__main__':
        temp1 = "xiaoqiang"
        print("temp var1 before: %s value: %s"%(id(temp1),temp1)) #140611843258912
        getVar(temp1)
        print("temp var1 after: %s  value: %s"%(id(temp1),temp1)) #140611843258768
    
    
    

    全局变量在传参前后,内存地址不会改变,这很合理。

    当全局变量被当作参数传到函数中时,这时候就是独立的存在了(局部变量),它的改变不会影响到全局变量的值和内存地址。

    全局变量在得到声明修改内容后,一样不会影响到已经作为局部变量的值和内存地址,只会影响全局变量本身。

    这里更改前局部变量和全局变量内存地址都是一样的,我猜测,可能python的存储是类似链表的结构,节省内存开销。

    相同值的情况下,会共用指向同一个内存。只有值改变,才会申请新的内存,这很合理~(mac和windows的输出一样)

    奇怪的地方

    mac 多进程,可以正常打印:

    #!/usr/bin/python
    #-*- coding: utf-8
    import multiprocessing
    def fun(name):
        print(test)
    if __name__=="__main__":
        test = "lll"
        pool = multiprocessing.Pool(3)
        for i in range(1,6):
            st = "start {}".format(i)
            pool.apply_async(func=fun,args=(st,))
        pool.close()
        pool.join()
    

    而Windows 多进程打印为空,如果想要打印全局变量test,必须要在函数前声明该变量,不管怎么global声明都不行,必须要在函数前面定义

    #-*- coding: utf-8
    #多进程作用域,变量必须要声明到函数前面
    test = "lll"
    def fun(name):
        print(test)
    if __name__=="__main__":
        # test = "lll"
        pool = multiprocessing.Pool(3)
        for i in range(1,6):
            st = "start {}".format(i)
            pool.apply_async(func=fun,args=(st,))
        pool.close()
        pool.join()
    

    多线程Mac &&Windows却都可以访问全局变量

    import threading
    import time
    
    
    def work1():
        global g_num
        for i in range(3):
            g_num += 1
        print("in work1 g_num is : %d" % g_num)
    
    def work2():
        print("in work2 g_num is : %d" % g_num)
    
    if __name__ == '__main__':
        g_num = 100
        t1 = threading.Thread(target=work1)
        t1.start()
        time.sleep(1)
        t2 = threading.Thread(target=work2)
        t2.start()
    '''
    in work1 g_num is : 103
    in work2 g_num is : 103
    '''
    

    多进程的处理,在windows那边一定要注意全局变量声明位置。

    多线程没有问题。

    不清楚mac和windows为什么有这个差异...先记录下来以后再来补充

  • 相关阅读:
    C#与C++与互操作
    WPF GridView动态添加项并读取数据
    C#使用消息队列(MSMQ)
    使用代码浏览WPF控件模版
    PowerShell将运行结果保存为文件
    opencv + ffmpeg
    vmware
    HttpComponents Downloads
    pytorch 安装
    opencv 3.4.0 的编译
  • 原文地址:https://www.cnblogs.com/xiaoqiangink/p/14138147.html
Copyright © 2011-2022 走看看