zoukankan      html  css  js  c++  java
  • Python_关于多线程下变量赋值取值的一点研究

    关于多线程下变量赋值取值的一点研究

     

    by:授客 QQ1033553122

    1.代码实践1

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-

    __author__ = 'shouke'

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-

    import threading
    import time

    class TestClass:
        def __init__(self, num):
            self.num = num

    global_var = 0
    def testfn(num, obj):
        global  global_var
        global_var = num
        local_var = num * 2
        obj.num = num * 2
        time.sleep(5)

        print("thread id:", threading.get_ident(), 'num:', num, 'obj.num:', obj.num, 'local_var:', local_var, 'global_var:', global_var)

    for i in range(0, 5):
        # # 多线程执行性能监控
        thread = threading.Thread(target=testfn,
                                  name="testfn"+str(i),
                                  args=(i, TestClass(i)))
        thread.start()

     

    Python_关于多线程下变量赋值取值的一点研究

     

     

    结论:

    1、如下,通过args给线程即将调用函数(为方便描述,暂且称它为 “线程函数”)传递参数,可以做到每个线程都使用各自的参数去调用线程函数。

    thread = threading.Thread(target=testfn,
                                  name="testfn"+str(i),
                                  args=(i, TestClass(i)))

    2、如下,线程函数里的局部变量(例中除去global_var之外的变量),都存储在栈内存中,而每个线程都有自己的栈内存,彼此独立,所以,每个线程对局部变量的赋值,读取操作互不影响。也就是说,多线程并发的情况下,局部变量是“安全”的,而全局变量存储在堆内存中,堆内存为所有线程共享,对所有线程都是可见的,所以两个以上的线程访问全局变量时,就会出现所谓的“不安全”,如下,第一个线程访问了全局变量 global_var,赋值为对应的num,然后中间sleep5秒,在此期间,另一个线程访问了全局变量,赋值为另一个num,然后第一个线程醒来了,发现全局变量 global_var 已经不是它要的值了。

    def testfn(num, obj):
        global  global_var
        global_var = num
        local_var = num * 2
        obj.num = num * 2
        time.sleep(5)

    2.代码实践2

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-

    import threading
    import time


    thread_local_obj = threading.local()

    class TestClass:
        def __init__(self, num):
            self.num = num

    global_var = 0
    def testfn(num, obj):
        global  global_var
        global_var = num
        local_var = num * 2
        obj.num = num * 2

        thread_local_obj.obj = obj
        time.sleep(5)


        other_task()

        print("thread id:", threading.get_ident(), 'num:', num, 'obj.num:', obj.num, 'local_var:', local_var, 'global_var:', global_var)

    def other_task():
        print("thread id:", threading.get_ident(), 'obj.num:', thread_local_obj.obj.num , threading.currentThread().name)


    for i in range(0, 5):
        # # 多线程执行性能监控
        thread = threading.Thread(target=testfn,
                                  name="testfn"+str(i),
                                  args=(i, TestClass(i)))
        thread.start()

     


    Python_关于多线程下变量赋值取值的一点研究


    如上,线程函数中调用了另一个函数,我们希望在这个函数中做些操作,比如读取和线程关联的对象的属性值、修改属性值,这个按常规思维也可以通过传递函数参数来实现,  如下 

    other_task(obj):

    print(obj.num)

    问题是,线程函数里可能会调用多个函数,被调用的每个函数也可能会调用多个函数,所有这些函数都可能用到线程关联的对像,这样的话,需要逐层传递参数,很麻烦

     

    解决方案:

    创建全局对象,如下

    thread_local_obj = threading.local()

    然后在 线程函数 里通过 thread_local_obj.attr = xxx 的方式,绑定线程关联的东西,其它地方使用时,会自动匹配与线程关联的值

     

  • 相关阅读:
    博客地址
    node学习2
    正则表达式总结
    Git命令操作
    IDEA快捷键
    hibernate多对多(权限管理)
    所有国家的下拉框英文全称
    所有国家的下拉框英文简写
    所有国家的下拉框中文
    poj-1248 Safecracker
  • 原文地址:https://www.cnblogs.com/shouke/p/10157490.html
Copyright © 2011-2022 走看看