# 基础知识篇
# 多线程
# Basic
线程为程序的最小执行单位,在 python 中用 Thread 库来控制线程。
import threading | |
import time | |
# 通过类携带 target 参数,直接生成线程类,同时,current_thread ().name 可以返回当前类的名称,线程的实例化可以通过调用 is_alive () 来判断线程是否存在。 | |
def test1(): | |
for i in range(5): | |
print(threading.current_thread().name,i) | |
time.sleep(1) | |
def test2(): | |
for i in range(5,10): | |
print(threading.current_thread().name,i) | |
time.sleep(1.5) | |
thread1 = threading.Thread(target=test1, daemon=True) | |
# thread2 = threading.Thread(target=test2) | |
# thread2.start() | |
thread1.start() | |
#join 用于对当前线程阻塞 | |
thread1.join(2) | |
for i in range(5): | |
print(threading.current_thread().name+' main ', i, thread1.is_alive()) |
daemon 设置为 True, 可以在主线程结束时,结束当前线程。
对线程类继承
class NewThread(threading.Thread): | |
def __init__(self, name=None): | |
super().__init__(name=name) | |
def run(self): | |
for i in range(10): | |
print(threading.current_thread().name) | |
time.sleep(1) | |
thread = NewThread() | |
thread.start() |
# 线程池
要想批量创建线程,同时给与每个线程分配任务,就需要线程池。
主要功能:
- 提前性,在分配任务前,就提前创建好线程,供给分配。
- 复用性,结束任务的线程放回线程池,供给下一次使用。
要满足创造线程的数量恒定,以及线程结束后的复用,那么就需要用到队列。
# quene
import threading | |
import time | |
from queue import Queue | |
class Mythread(threading.Thread): | |
def __init__(self, que): | |
threading.Thread.__init__(self) | |
self.queue = que | |
def run(self): | |
while True: | |
time.sleep(1) | |
if self.queue.empty(): # 判断放到 get 前面,这样可以,否则队列最后一个取完后就空了,直接 break,走不到 print | |
break | |
print('队列的长度', self.queue.qsize()) | |
item = self.queue.get() | |
print(item, '!', threading.current_thread().name) | |
# 队列包含内置运行状态 unfinished_tasks 表示剩余任务队列的状态,假如队列中没有任务则停止 | |
self.queue.task_done() | |
# 貌似会先吧 join 前的任务全放入队列 | |
que = Queue() | |
# 创建线程队列,这里创建了 2 个线程 | |
tasks = [Mythread(que) for x in range(2)] | |
#指定任务队列,用于生产任务,这里生产了 5 个任务 | |
for x in range(5): | |
que.put(x) # 快速生产 | |
for x in tasks: | |
x.start() # 把同一个队列传入 2 个线程 | |
for i in range(10): | |
que.put(i) | |
que.join() | |
print('success') |
上述已经展示了任务队列以及多线程的简单使用。