本章主要学习如何使用多线程
github博客传送门
csdn博客传送门
Python通过threading模块提供对线程的支持
threading常用方法:
threading.Thread(target=需要开启多线程的方法注意不要加括号, name='设置的线程名字(可选)', args=(传入方法的参数,可选如果只有一个参数 参数后要加逗号.))
threading.current_thread() # 返回当前进程的详细信息
threading.currentThread(): # 返回当前的线程变量。
threading.enumerate(): # 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): # 返回正在运行的线程数量,len(threading.enumerate())有相同的结果。
我们来看个例子吧:
import threading # 导入threading模块
def print_0_9(): # 我们定义一个输出1-10的函数
for i in range(10): # 我们用range生成 0-9这个数
# 我们使用threading.current_thread()获取进程的方法之上 再使用.getName()方法读取到进程的名字
print('这是线程{}:{}'.format(threading.current_thread().getName(), i))
# 我们定义一个主函数
def main():
# 创建一个线程 设置线程名为 1 调用 print_0_9 这个函数 注意 函数名后面一定一定不要加括号
thread1 = threading.Thread(target=print_0_9, name='1')
thread2 = threading.Thread(target=print_0_9, name='2') # 再创建一个线程 设置线程名为 2
thread3 = threading.Thread(target=print_0_9, name='3') # 创建一个名为 3 的线程
thread1.start() # 启动线程 1
thread2.start() # 启动线程 2
thread3.start() # 启动线程 3
main() # 调用 main 函数
# 结果 你会看到三条交替运行的线程 有时会出现没有交替的情况,再跑一次程序就好了.
Thread类方法
run(): # 用以表示线程活动的方法。
start(): # 启动线程活动。
join([time]): # 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
isAlive(): # 返回线程是否活动的。
getName(): # 返回线程名。
setName(): # 设置线程名。
使用继承类创建线程的方法:
import threading, time # 导入线程模块 时间模块(用来暂停程序)
def print_0_9(delay): # 定义一个输出函数 输出 0-9 个数 ,传入一个延迟 秒数
for i in range(10): # range生成 0-9 个数
time.sleep(delay) # 暂停程序 delay 秒
print('这是{}:{}'.format(threading.current_thread().getName(), i)) # 打印出线程的名字 和range生成的值
class myThread(threading.Thread): # 定义一个 我的Thread类
def __init__(self, name, delay): # 初始化函数 传入进程名 延时秒数
# 二选一
threading.Thread.__init__(self) # 等效于super().__init__() # 父类初始化
# super().__init__() # 等效于threading.Thread.__init__(self) # 父类初始化
self.name = name
self.delay = delay
def run(self): # 继承Thread类 线程从这个方法开始
print_0_9(self.delay) # 线程 和传入的参数
if __name__ == '__main__': # 主函数入口
# 创建两个线程
thread1 = myThread('线程一', 0.5)
thread2 = myThread('线程二', 1)
# 开启线程
thread1.start()
thread2.start()
# 执行结果 两个线程交替运行打印出 0-9 的数值
线程等待
import threading # 导入threading类
def m1(): # 定义了一个 m1 函数 输出 0-9 个数
for i in range(10):
print(threading.current_thread().getName(), i) # 打印线程名 由于没有设置线程名 会使用默认线程名字
if i == 5: # 在输出了 i == 5 之后线程等待
thread2 = threading.Thread(target=m2, name='线程二') # 创建线程二 插入 m2 函数
thread2.start() # 启动线程
thread2.join() # join线程 你可以尝试注释这句看看执行效果
def m2(): # 定义了一个 m2函数 输出 10-19个数
for i in range(10, 20):
print(threading.current_thread().getName(), i) # 打印线程名 和输出的值 i
m1() # 执行m1线程观察线程等待
# 输出结果 在输出了 5 之后 执行 m2 函数输出 m2里的值 输完之后在继续输出上一个线程的值.
线程通信
线程共享同一个资源 可以使用globals或在方法外创建一个资源
import threading, time # 导入threading和time模块类
# 使用多线程, 模拟生活中的多窗口售票,这里演示四个窗口售票
listA = [x for x in range(1, 101)] # 定义一个票仓库 装 1-100号的票
def sell_ticket(): # 定义了一个售票的方法
while listA: # 当listA里有票的时候执行卖票
a = listA.pop() # 使用list的pop方法取出一张票赋值给a
time.sleep(0.1) # 等待0.1秒
print('窗口{}:卖出的票号为 {}'.format(threading.current_thread().getName(), a)) # 打印当前线程名字 和 卖出的票号
else:
print('票卖完了') # 当listA里的票卖完后 执行本句
class myThread(threading.Thread): # 定义一个类 继承 threading.Thread
def __init__(self, name): # 初始化方法 传入线程名字
threading.Thread.__init__(self) # 父类初始化
# super().__init__() # 父类初始化
self.name = name
def run(self): # 父类继承过来的方法
sell_ticket() # 需要执行的 方法
if __name__ == '__main__': # 主函数入口
# 创建四个线程
thread1 = myThread('一') # 线程名 一
thread2 = myThread('二') # 线程名 二
thread3 = myThread('三') # 线程名 三
thread4 = myThread('四') # 线程名 四
# 开启线程
thread1.start() # 线程一开启
thread2.start() # 线程二开启
thread3.start() # 线程三开启
thread4.start() # 线程四开启