• python多线程示例2,加锁(仅仅作为记录)


     1 import threading
     2 
     3 # 多线程本质上是在一个 Python 程序里做的一个资源再分配,把几段代码的运行顺序进行先后调整达到 CPU 资源利用的最大化。
     4 # 但是这么做的一个缺点就是资源竞争Resource Contention,意思就是有可能几段代码同时在读写一个参数的时候,把这个参数的数值搞混。
     5 # 所以在多线程共享资源的情况下,需要在共享资源外部添加锁 Lock。
     6 
     7 # 直接继承线程类,然后覆盖继承类函数的方法
     8 class ThreadChild(threading.Thread):
     9     # 初始化 init: 通常继承线程类会扩写父类的初始化,来传递参数等。
    10     def __init__(self, times, name, ret_dic, ret_lock):
    11         # 扩写父类的初始化,首先调用父类的初始化
    12         threading.Thread.__init__(self)
    13         self.times = times
    14         self.name = name
    15         self.ret_dic = ret_dic
    16         self.ret_lock = ret_lock
    17         return
    18     # 运行 run: 这是一个必须要覆盖的函数。启动线程调用的 start() 函数就是运行这个函数,这里是需要运行的核心代码。
    19     def run(self):
    20         # 覆盖重写函数 run
    21         for i in range(self.times):
    22             print(self.name + ' run: ' + str(i))
    23         self.ret_lock.acquire()# 锁住, 锁住之后的代码将只能被一个线程执行下去,直到开锁
    24         # 进入有可能竞争的共享资源,锁住
    25         self.ret_dic[self.name] = self.name + " finished with " + str(self.times) + " times printed"
    26         # 共享资源读写结束,开锁
    27         self.ret_lock.release()# 开锁, 开锁之后,被锁住的资源和代码行又可以重新被其他线程读写
    28         return
    29 
    30 if __name__ == '__main__':
    31 
    32     thread_pool = []
    33     ret_dic = {}
    34     # 锁类 Lock: 在线程中需要读写一个共享资源的时候,通过锁类来锁住资源,防止另外的线程读写修改。
    35     # 这里在主程序中创建了一个锁 ret_lock, 并且传入了两个线程中。
    36     # 这个锁本身是可以在多个线程中共享的,因为锁本身不存在资源竞争的问题,否则就没有意义了。
    37     ret_lock = threading.Lock()
    38     th_1 = ThreadChild(times=3, name='th_1', ret_dic=ret_dic, ret_lock=ret_lock)
    39     th_2 = ThreadChild(times=5, name='th_2', ret_dic=ret_dic, ret_lock=ret_lock)
    40     thread_pool.append(th_1)
    41     thread_pool.append(th_2)
    42 
    43     # 非阻塞 start()
    44     for th in thread_pool:
    45         th.start()
    46 
    47     # 阻塞 join()
    48     for th in thread_pool:
    49         th.join()
    50 
    51     print(ret_dic)
    52 
    53     # 锁类 Lock: 在线程中需要读写一个共享资源的时候,通过锁类来锁住资源,防止另外的线程读写修改。
    54     #           这里在主程序中创建了一个锁 ret_lock, 并且传入了两个线程中。
    55     #           这个锁本身是可以在多个线程中共享的,因为锁本身不存在资源竞争的问题,否则就没有意义了。
    56     # 锁住 Acquire: Acquire() 是锁的一个函数,表示获得资源,也可以表示锁住资源。在这个函数之后的代码将只能被一个线程执行下去,直到开锁。
    57     # 开锁 Release: Release() 是锁的一个函数,表示释放资源,也可以表示开锁。开锁之后,被锁住的资源和代码行又可以重新被其他线程读写,运行。
    58 
    59     # 全局变量也是 Python 程序的共享资源,在多线程运算中,接触到全局变量的地方都需要加锁,或者也可以直接把锁变成全局变量:
    60     # import threading
    61     # glob_lock = threading.Lock()
    62     # glob_a = 100
    63     # def increase_by_a(num): # 不好的例子,虽然对全局变量加了锁,但是在函数内部运用了全局变量
    64     #     glob_lock.acquire()
    65     #     result = glob_a + num
    66     #     glob_lock.release()
    67     #     return result
    68     # if __name__ == '__main__':
    69     #     print(increase_by_a(100)) # 返回 200
    70     #
    71     #     glob_lock.acquire()
    72     #     glob_a += 1
    73     #     glob_lock.release()
    74     #
    75     #     print(increase_by_a(100)) # 返回 201,glob_a的改变破坏了函数 increase_by_a 的一致性
    76     # 这里的锁是在全局变量中的,并且锁住了一个全局变量。
    77     # 但是我们会发现,两次调用 increase_by_a 函数的过程中,
    78     # 返回数值因为一个全局变量而变化了,尽管在函数传入的参数是一致的,这就破坏了函数的一致性:
    79     #     函数的一致性:每次在同一个函数传入相同的参数,返回相同的结果
    80     # 因此,尽量在函数中避免调用全局变量,或全局锁,以防破坏函数的一致性。
    个人学习记录
  • 相关阅读:
    Struts2中Date日期转换的问题
    IE SEESION共享的问题
    ORA-12518,TNS:listener could not hand off client connection
    TypeError: validator.settings[("on" + event.type)].call is not a function
    org.apache.ibatis.reflection.ReflectionException
    java.lang.IllegalArgumentException
    那些年,我追过的绘图工具
    spring使用rssfeed
    RSS Feeds with Spring Boot
    highcharts 动态生成x轴和折线图
  • 原文地址:https://www.cnblogs.com/jeshy/p/15234059.html
Copyright © 2020-2023  润新知