首页 > 解决方案 > 变量范围(带线程)

问题描述

我在两个模块中有以下代码。

模块“主要”:

#!/usr/bin/python

import threading
import b

a = 0

def api_a():
    global a
    print("api_a()")
    a = 1

def main():
    global a

    thread_B = b.B_thread()

    print("a = " + str(a)) 

    thread_B.start()

#    api_a()

    thread_B.join()

    print("a = " + str(a)) 

if __name__ == '__main__':
    main()

模块“B”:

#!/usr/bin/python

import threading
import main

class B_thread (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        print("Starting " + self.name)
        B_process()
        print("Exiting " + self.name)

def B_process():
    main.api_a()

如果我运行此代码,我会得到:

a = 0
Starting Thread-1
api_a()
Exiting Thread-1
a = 0

为什么变量“a”没有设置为“1”?

如果我激活模块“main”( api_a() )中注释的代码行,变量“a”将设置为“1”。为什么通过线程调用函数 api_a() 时没有设置变量?

在示例代码中,我跳过了使用锁来使代码线程安全。

有任何想法吗?

非常感谢提前,

托马斯

标签: pythonmultithreading

解决方案


出现这种行为是因为您将main.py其作为参数传递给了 python ( python main.py)。

当您以这种方式执行脚本时,python 将main模块解释为__main__,但b模块仍会更新main.a变量而不是__main__.a,因为b已将您的 main.py 模块重新导入为main.

因此,为了使其工作,我们可以从模块的角度更新__main__.a函数api_ab打印main.a变量,而不是__main__.a__main__模块的角度。

def api_a():
    print("api_a()")
    import sys
    sys.modules['__main__'].a = 1

或者

def main():
    ...
    thread_B.join()
    import sys
    print("a = " + str(sys.modules['main'].a))

__main__文档


推荐阅读