MST

星途 面试题库

面试题:Python多线程编程在I/O密集型任务中的应用

请阐述Python多线程为何适用于I/O密集型任务,并举例说明如何使用`threading`模块实现一个简单的I/O密集型多线程任务,比如同时读取多个文件的内容。
44.1万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

Python多线程适用于I/O密集型任务的原因

  1. GIL(全局解释器锁)影响:Python的多线程在CPU密集型任务中会受到GIL的限制,因为GIL同一时刻只允许一个线程在CPU上执行字节码,无法利用多核优势。但在I/O密集型任务中,线程在进行I/O操作(如文件读写、网络请求等)时,会释放GIL,使得其他线程有机会获取GIL并执行,从而实现多个I/O操作的并发执行,提高整体效率。
  2. I/O操作特性:I/O操作通常比CPU计算慢得多,在等待I/O操作完成的过程中,线程处于空闲状态。多线程可以在一个线程等待I/O时,切换到其他线程执行,充分利用这段等待时间,提升程序的整体运行效率。

使用threading模块实现简单I/O密集型多线程任务(同时读取多个文件内容)

import threading


def read_file(file_path):
    try:
        with open(file_path, 'r') as file:
            content = file.read()
            print(f"Read content from {file_path}: {content}")
    except FileNotFoundError:
        print(f"File {file_path} not found.")


if __name__ == '__main__':
    file_paths = ['file1.txt', 'file2.txt', 'file3.txt']
    threads = []
    for file_path in file_paths:
        thread = threading.Thread(target=read_file, args=(file_path,))
        threads.append(thread)
        thread.start()
    for thread in threads:
        thread.join()

在上述代码中:

  1. 定义了read_file函数,该函数接受一个文件路径作为参数,尝试打开文件并读取其内容。如果文件不存在,则捕获FileNotFoundError并打印提示信息。
  2. if __name__ == '__main__':代码块中,首先定义了一个包含多个文件路径的列表file_paths
  3. 然后,通过循环为每个文件路径创建一个新的线程,线程的目标函数为read_file,并将文件路径作为参数传递给目标函数。创建线程后启动线程。
  4. 最后,通过另一个循环调用每个线程的join方法,等待所有线程完成,确保主线程在所有文件读取操作完成后再退出。