此类表示在单独的控制线程中运行的活动, 有两种方法可以指定该活动, 一是将可调用对象传递给构造函数, 二是通过覆盖子类中的 run() 方法.
如果你对线程不太理解, 我们可以打个比方, 把线程数看作车辆数, 我们来完成一个简单的客运运输工作 (以下为了方便理解, 也加入相应注释).
更多 threading 模块函数和对象说明, 可参考: https://www.cnblogs.com/leozhanggg/p/10317494.html
一, 无线程:
示例:
- import time
- start = time.time()
- people = 500 # 假设有 500 个人
- def action(num):
- global people
- while people>0:
- people -= 50 # 每次运输 50 人
- print("车辆编号:%d, 当前车站人数:%d" %(num, people))
- time.sleep(1)
- num = 1 # 车辆编号
- action(num)
- end = time.time()
- print("Duration time: %0.3f" %(end-start))
运行结果:
C:\Python37\python.exe Y:/Project-python/threading/test.py
车辆编号: 1, 当前车站人数: 450
车辆编号: 1, 当前车站人数: 400
车辆编号: 1, 当前车站人数: 350
车辆编号: 1, 当前车站人数: 300
车辆编号: 1, 当前车站人数: 250
车辆编号: 1, 当前车站人数: 200
车辆编号: 1, 当前车站人数: 150
车辆编号: 1, 当前车站人数: 100
车辆编号: 1, 当前车站人数: 50
车辆编号: 1, 当前车站人数: 0
- Duration time: 10.001
- Process finished with exit code 0
二, 单线程:
编码示例:
- import threading
- import time
- start = time.time()
- people = 500 # 假设有 500 个人
- def action(num):
- global people
- while people>0:
- people -= 50 # 每次运输 50 人
- print("车辆编号:%d, 当前车站人数:%d" %(num, people))
- time.sleep(1)
- num = 1 # 车辆编号
- vehicle = threading.Thread(target=action, args=(num,)) # 新建车辆
- vehicle.start() # 启动车辆
- vehicle.join() # 检查到站车辆
- end = time.time()
- print("Duration time: %0.3f" %(end-start))
运行结果:
C:\Python37\python.exe Y:/Project-python/threading/test.py
车辆编号: 1, 当前车站人数: 450
车辆编号: 1, 当前车站人数: 400
车辆编号: 1, 当前车站人数: 350
车辆编号: 1, 当前车站人数: 300
车辆编号: 1, 当前车站人数: 250
车辆编号: 1, 当前车站人数: 200
车辆编号: 1, 当前车站人数: 150
车辆编号: 1, 当前车站人数: 100
车辆编号: 1, 当前车站人数: 50
车辆编号: 1, 当前车站人数: 0
- Duration time: 10.001
- Process finished with exit code 0
三, 多线程 (传递对象方式):
编码示例:
- # -*- coding: utf-8 -*
- import threading
- import time
- people = 500
- class MyThread(threading.Thread):
- def __init__(self, num):
- super(MyThread, self).__init__()
- self.num = num
- def run(self):
- global people
- while people> 0:
- people -= 50
- print("车辆编号:%d, 当前车站人数:%d" % (self.num, people))
- time.sleep(1)
- start = time.time()
- vehicles = [] # 新建车辆组
- for num in range(5): # 设置车辆数
- vehicle = MyThread(num) # 新建车辆
- vehicles.append(vehicle) # 添加车辆到车辆组中
- vehicle.start() #启动车辆
- for vehicle in vehicles:
- vehicle.join() # 分别检查到站车辆
- end = time.time()
- print("Duration time: %0.3f" % (end-start))
运行结果:
C:\Python37\python.exe Y:/Project-python/threading/test.py
车辆编号: 0, 当前车站人数: 450
车辆编号: 1, 当前车站人数: 400
车辆编号: 2, 当前车站人数: 350
车辆编号: 3, 当前车站人数: 300
车辆编号: 4, 当前车站人数: 250
车辆编号: 2, 当前车站人数: 200
车辆编号: 1, 当前车站人数: 150
车辆编号: 0, 当前车站人数: 100
车辆编号: 3, 当前车站人数: 50
车辆编号: 4, 当前车站人数: 0
- Duration time: 2.001
- Process finished with exit code 0
四, 多线程 (覆盖子类方式)
编码示例:
- # -*- coding: utf-8 -*
- import threading
- import time
- people = 500
- class MyThread(threading.Thread):
- def __init__(self, num):
- super(MyThread, self).__init__()
- self.num = num
- def run(self):
- global people
- while people> 0:
- people -= 50
- print("车辆编号:%d, 当前车站人数:%d" % (self.num, people))
- time.sleep(1)
- start = time.time()
- vehicles = []
- for num in range(5):
- vehicle = MyThread(num)
- vehicles.append(vehicle)
- vehicle.start()
- for vehicle in vehicles:
- vehicle.join()
- end = time.time()
- print("Duration time: %0.3f" % (end-start))
运行结果:
C:\Python37\python.exe Y:/Project-python/threading/test.py
车辆编号: 0, 当前车站人数: 450
车辆编号: 1, 当前车站人数: 400
车辆编号: 2, 当前车站人数: 350
车辆编号: 3, 当前车站人数: 300
车辆编号: 4, 当前车站人数: 250
车辆编号: 0, 当前车站人数: 200
车辆编号: 2, 当前车站人数: 150 车辆编号: 3, 当前车站人数: 100 车辆编号: 1, 当前车站人数: 50
车辆编号: 4, 当前车站人数: 0
- Duration time: 2.003
- Process finished with exit code 0
五, 结果分析
1. 通过结果不难发现, 不使用线程类和使用单线程运行时间是一样的, 因为我们正常执行一个脚本, 本质上就是单线程.
2. 创建多线程的两种方法运行时间也是一样的, 因为最终都是交给 Thread 类来处理, 自行选择即可.
3. 多线程运行时间明显比单线程快的多, 从理论上来说是和线程数成正比的, 但是实际并非是线程越多越好, 因为线程越多所消耗的资源也就越多.
六, 有关该类的其他说明:
a. 创建线程对象后, 必须通过调用线程的 start() 方法启动其活动, 这将在单独的控制线程中调用 run() 方法.
b. 一旦线程的活动开始, 线程就被认为是 "活着的", 当 run() 方法终止时, 它会停止活动, 或者引发异常.
c. 线程可以调用 is_alive() 方法测试是否处于活动状态, 其他线程可以调用线程的 join() 方法, 这将阻塞调用线程, 直到调用其 join() 方法的线程终止.
d. 线程有一个名称, 这个名称可以传递给构造函数, 并通过 name 属性读取或更改.
e. 线程可以标记为 "守护程序线程", 这个标志的意义在于, 当只剩下守护进程线程时, 整个 Python 程序都会退出, 可以通过守护程序属性设置该标志.
----- 菜鸟随笔, 欢迎各路大神指点.
----- 转载请注明原作, 谢谢: https://www.cnblogs.com/leozhanggg/p/10335098.html
来源: https://www.cnblogs.com/leozhanggg/p/10335098.html