一、多线程
有两种方式来创建线程:一种是继承Thread类,并重写它的run( )方法;另一种是实例化threading.Thread对象的时候,将线程要执行的任务函数作为参数传入线程。
第一种方法:
import threading
class MyThread(threading.Thread):
def __init__(self, thread_name):
# 注意:一定要显式的调用父类的初始化函数。
super(MyThread, self).__init__(name=thread_name)
def run(self):
print("%s正在运行中......" % self.name)
if __name__ == '__main__':
for i in range(10):
MyThread("thread-" + str(i)).start()
import threading
class MyThread(threading.Thread):
def __init__(self, thread_name):
# ()里的参数可以单独拿出来赋值
super(MyThread, self).__init__()
self.name = thread_name
def run(self):
print(f"{self.name}正在运行中......")
if __name__ == '__main__':
for i in range(10):
MyThread("thread-" + str(i)).start()
第二种方法:
import threading
def show(arg):
print('thread '+str(arg)+" running....")
if __name__ == '__main__':
for i in range(10):
# target: 线程要执行的函数,args: 线程函数的参数
t = threading.Thread(target=show, args=(i,))
t.start()
Thread类 定义
对于Thread类,它的定义如下:
threading.Thread(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None)
- 参数group是预留的,用于将来扩展;
- 参数target是一个可调用对象,在线程启动后执行;
- 参数name是线程的名字。默认值为“Thread-N“,N是一个数字。
- 参数args和kwargs分别表示调用target时的参数列表和关键字参数。
二、线程池
线程池是一种基于池化思想管理线程的工具。在开始任务时不再重新创建新的线程,而是直接从线程池中获取一个空闲线程来执行。如果线程池中没有空闲线程,新的任务就会等待(排队),直到有线程空闲。当任务执行完毕后,线程并不立即销毁,而是返回线程池等待下次被利用。
线程池的创建
from concurrent.futures import ThreadPoolExecutor
import time
def task(n):
print(f"Task {n} started")
time.sleep(1) # 模拟耗时操作
return f"Task {n} completed"
# 创建一个最大线程数为3的线程池
with ThreadPoolExecutor(max_workers=3) as executor:
# 提交5个任务
futures = [executor.submit(task, i) for i in range(5)]
# 获取结果
for future in futures:
print(future.result())
线程池的常见用途包括:
- 并行I/O操作:
- 同时处理多个网络请求
- 并行文件读写操作
- 并行计算:
- 将大型计算任务分解为小任务并行处理
- 定时任务调度:
- 管理需要定期执行的任务
- 异步回调处理:
- 处理异步操作的回调
- 批量数据处理:
- 并行处理大量数据项
Comments NOTHING