zoukankan      html  css  js  c++  java
  • python多线程示例3,加锁(仅仅作为记录)

     1 import threading
     2 import math
     3 import datetime
     4 
     5 # 多线程本质上是在一个 Python 程序里做的一个资源再分配,把几段代码的运行顺序进行先后调整达到 CPU 资源利用的最大化。
     6 # 但是这么做的一个缺点就是资源竞争Resource Contention,意思就是有可能几段代码同时在读写一个参数的时候,把这个参数的数值搞混。
     7 # 所以在多线程共享资源的情况下,需要在共享资源外部添加锁 Lock。
     8 
     9 # 直接继承线程类,然后覆盖继承类函数的方法
    10 class ThreadChild(threading.Thread):
    11     # 初始化 init: 通常继承线程类会扩写父类的初始化,来传递参数等。
    12     def __init__(self, num_list, name, ret_dic, ret_lock):
    13         # 扩写父类的初始化,首先调用父类的初始化
    14         threading.Thread.__init__(self)
    15         self.num_list = num_list
    16         self.name = name
    17         self.ret_dic = ret_dic
    18         self.ret_lock = ret_lock
    19         return
    20 
    21     # 运行 run: 这是一个必须要覆盖的函数。启动线程调用的 start() 函数就是运行这个函数,这里是需要运行的核心代码。
    22     def run(self):# 覆盖重写函数 run
    23         result = 0
    24         for num in self.num_list:
    25             result += math.sqrt(num * math.tanh(num) / math.log2(num) / math.log10(num))
    26         self.ret_lock.acquire()# 锁住, 锁住之后的代码将只能被一个线程执行下去,直到开锁
    27         self.ret_dic[self.name] = result
    28         self.ret_lock.release()# 开锁, 开锁之后,被锁住的资源和代码行又可以重新被其他线程读写
    29         return
    30 
    31 
    32 if __name__ == '__main__':
    33 
    34     thread_pool = []
    35     ret_dic = {}
    36     # 锁类 Lock: 在线程中需要读写一个共享资源的时候,通过锁类来锁住资源,防止另外的线程读写修改。
    37     ret_lock = threading.Lock()
    38 
    39     # 多线程
    40     th_1 = ThreadChild(num_list=list(range(10, 3000000)), name='th_1', ret_dic=ret_dic, ret_lock=ret_lock)
    41     th_2 = ThreadChild(num_list=list(range(3000000, 6000000)), name='th_2', ret_dic=ret_dic, ret_lock=ret_lock)
    42     th_3 = ThreadChild(num_list=list(range(6000000, 9000000)), name='th_3', ret_dic=ret_dic, ret_lock=ret_lock)
    43     thread_pool.append(th_1)
    44     thread_pool.append(th_2)
    45     thread_pool.append(th_3)
    46 
    47     start_t = datetime.datetime.now()
    48 
    49     # 非阻塞 start()
    50     for th in thread_pool:
    51         th.start()
    52 
    53     # 阻塞 join()
    54     for th in thread_pool:
    55         th.join()
    56 
    57     final_result = sum(ret_dic.values())
    58     end_t = datetime.datetime.now()
    59     elapsed_sec = (end_t - start_t).total_seconds()
    60     print("多线程计算结果: " + "{:.1f}".format(final_result) + ", 共消耗: " + "{:.2f}".format(elapsed_sec) + "")
    61 
    62     # 单线程
    63     ret_dic.clear()
    64     th_4 = ThreadChild(num_list=list(range(10, 9000000)), name='th_4', ret_dic=ret_dic, ret_lock=ret_lock)
    65     start_t = datetime.datetime.now()
    66     th_4.start()# 非阻塞 start()
    67     th_4.join()# 阻塞 join()
    68     final_result = sum(ret_dic.values())
    69     end_t = datetime.datetime.now()
    70     elapsed_sec = (end_t - start_t).total_seconds()
    71     print("单线程计算结果: " + "{:.1f}".format(final_result) + ", 共消耗: " + "{:.2f}".format(elapsed_sec) + "")
    72 
    73     # 多线程计算结果: 1484922580.2, 共消耗: 8.72 秒
    74     # 单线程计算结果: 1484922580.2, 共消耗: 4.03 秒
    75 
    76     # 把这两行注释掉
    77     # th_3 = ThreadChild(num_list=list(range(6000000, 9000000)), name='th_3', ret_dic=ret_dic, ret_lock=ret_lock)
    78     # thread_pool.append(th_3)
    79     # 多线程计算结果: 830326785.5, 共消耗: 3.01 秒
    80     # 单线程计算结果: 1484922580.2, 共消耗: 4.21 秒
    81 
    82     # 多线程本质上还是在一个进程里做的资源分配优化,还没有利用到多进程,多核心计算的能力。
    83     # 但是多线程的巨大优势是在遇到阻塞型函数,例如 API 调用,网络通信,文件读写的时候,
    84     # 可以不被网络速度,硬盘速度耽误了程序其他部分的运算。
    85 
    86     # 以上 Python 的多线程模块来实现计算提速,但是受限于在一个进程,也就是单核心上的运算
    个人学习记录
  • 相关阅读:
    mysql索引数据结构
    29. 使用参数化编写自动化测试用例
    28. Python编写自动化测试用例
    27. Unittest单元测试框架的介绍与使用
    26. 什么是单元测试
    25. Postman的使用
    24. 接口测试的意义
    23. requests安装与使用
    22. 如何编写接口文档
    21. Blog接口开发
  • 原文地址:https://www.cnblogs.com/jeshy/p/15234062.html
Copyright © 2011-2022 走看看