一、多线程

有两种方式来创建线程:一种是继承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())

线程池的常见用途包括:

  1. 并行I/O操作:
    • 同时处理多个网络请求
    • 并行文件读写操作
  2. 并行计算:
    • 将大型计算任务分解为小任务并行处理
  3. 定时任务调度:
    • 管理需要定期执行的任务
  4. 异步回调处理:
    • 处理异步操作的回调
  5. 批量数据处理:
    • 并行处理大量数据项