首页 后端开发 Python教程 了解 Python 中的线程和多重处理:综合指南

了解 Python 中的线程和多重处理:综合指南

Sep 12, 2024 pm 02:17 PM

Understanding Threading and Multiprocessing in Python: A Comprehensive Guide

介绍

在 Python 中,在优化应用程序性能时,尤其是当它们涉及并发或并行执行时,经常会讨论 线程多处理 的概念。尽管术语有重叠,但这两种方法本质上是不同的。

本博客将有助于澄清线程多处理的混淆,解释何时使用每个概念,并为每个概念提供相关示例。


线程与多处理:主要区别

在深入示例和用例之前,让我们概述一下主要区别:

  • 线程:是指在单个进程中运行多个线程(进程的较小单元)。线程共享相同的内存空间,这使得它们变得轻量级。然而,Python 的全局解释器锁 (GIL) 限制了 CPU 密集型任务的线程的真正并行性。

  • 多处理:涉及运行多个进程,每个进程都有自己的内存空间。进程比线程重,但可以实现真正的并行性,因为它们不共享内存。这种方法非常适合需要充分利用核心的 CPU 密集型任务。


什么是线程?

线程是一种在同一进程中同时运行多个任务的方法。这些任务由线程处理,它们是共享相同内存空间的独立的轻量级执行单元。线程有利于 I/O 密集型操作,例如文件读取、网络请求或数据库查询,这些操作中主程序花费大量时间等待外部资源。

何时使用线程

  • 当您的程序受 I/O 限制时(例如,读/写文件、发出网络请求)。
  • 当任务花费大量时间等待输入或输出操作时。
  • 当您需要在单个进程中实现轻量级并发时。

示例:基本线程

import threading
import time

def print_numbers():
    for i in range(5):
        print(i)
        time.sleep(1)

def print_letters():
    for letter in ['a', 'b', 'c', 'd', 'e']:
        print(letter)
        time.sleep(1)

# Create two threads
t1 = threading.Thread(target=print_numbers)
t2 = threading.Thread(target=print_letters)

# Start both threads
t1.start()
t2.start()

# Wait for both threads to complete
t1.join()
t2.join()

print("Both threads finished execution.")

在上面的示例中,两个线程并发运行:一个打印数字,另一个打印字母。 sleep() 调用模拟 I/O 操作,程序可以在这些等待期间在线程之间切换。

线程问题:全局解释器锁 (GIL)

Python 的 GIL 是一种防止多个本机线程同时执行 Python 字节码的机制。它确保一次只有一个线程运行,即使进程中有多个线程处于活动状态。

此限制使得线程不适合需要真正并行性的 CPU 密集型任务,因为由于 GIL,线程无法充分利用多个内核。


什么是多重处理?

多处理允许您同时运行多个进程,其中每个进程都有自己的内存空间。由于进程不共享内存,因此没有 GIL 限制,允许在多个 CPU 内核上真正并行执行。多重处理非常适合需要最大化 CPU 使用率的 CPU 密集型任务。

何时使用多重处理

  • 当您的程序受 CPU 限制时(例如,执行繁重的计算、数据处理)。
  • 当您需要真正的并行性而不需要内存共享时。
  • 当您想要同时运行独立任务的多个实例时。

示例:基本多重处理

import multiprocessing
import time

def print_numbers():
    for i in range(5):
        print(i)
        time.sleep(1)

def print_letters():
    for letter in ['a', 'b', 'c', 'd', 'e']:
        print(letter)
        time.sleep(1)

if __name__ == "__main__":
    # Create two processes
    p1 = multiprocessing.Process(target=print_numbers)
    p2 = multiprocessing.Process(target=print_letters)

    # Start both processes
    p1.start()
    p2.start()

    # Wait for both processes to complete
    p1.join()
    p2.join()

    print("Both processes finished execution.")

在此示例中,两个单独的进程同时运行。与线程不同,每个进程都有自己的内存空间,并且独立执行,不受GIL的干扰。

多处理中的内存隔离

线程和多处理之间的一个关键区别是进程不共享内存。虽然这确保了进程之间没有干扰,但这也意味着它们之间共享数据需要特殊的机制,例如多处理模块提供的 Queue、Pipe 或 Manager 对象。


线程与多处理:选择正确的工具

现在我们了解了这两种方法的工作原理,让我们根据任务类型详细说明何时选择线程或多处理:

Use Case Type Why?
Network requests, I/O-bound tasks (file read/write, DB calls) Threading Multiple threads can handle I/O waits concurrently.
CPU-bound tasks (data processing, calculations) Multiprocessing True parallelism is possible by utilizing multiple cores.
Task requires shared memory or lightweight concurrency Threading Threads share memory and are cheaper in terms of resources.
Independent tasks needing complete isolation (e.g., separate processes) Multiprocessing Processes have isolated memory, making them safer for independent tasks.

Performance Considerations

Threading Performance

Threading excels in scenarios where the program waits on external resources (disk I/O, network). Since threads can work concurrently during these wait times, threading can help boost performance.

However, due to the GIL, CPU-bound tasks do not benefit much from threading because only one thread can execute at a time.

Multiprocessing Performance

Multiprocessing allows true parallelism by running multiple processes across different CPU cores. Each process runs in its own memory space, bypassing the GIL and making it ideal for CPU-bound tasks.

However, creating processes is more resource-intensive than creating threads, and inter-process communication can slow things down if there's a lot of data sharing between processes.


A Practical Example: Threading vs. Multiprocessing for CPU-bound Tasks

Let's compare threading and multiprocessing for a CPU-bound task like calculating the sum of squares for a large list.

Threading Example for CPU-bound Task

import threading

def calculate_squares(numbers):
    result = sum([n * n for n in numbers])
    print(result)

numbers = range(1, 10000000)
t1 = threading.Thread(target=calculate_squares, args=(numbers,))
t2 = threading.Thread(target=calculate_squares, args=(numbers,))

t1.start()
t2.start()

t1.join()
t2.join()

Due to the GIL, this example will not see significant performance improvements over a single-threaded version because the threads can't run simultaneously for CPU-bound operations.

Multiprocessing Example for CPU-bound Task

import multiprocessing

def calculate_squares(numbers):
    result = sum([n * n for n in numbers])
    print(result)

if __name__ == "__main__":
    numbers = range(1, 10000000)
    p1 = multiprocessing.Process(target=calculate_squares, args=(numbers,))
    p2 = multiprocessing.Process(target=calculate_squares, args=(numbers,))

    p1.start()
    p2.start()

    p1.join()
    p2.join()

In the multiprocessing example, you'll notice a performance boost since both processes run in parallel across different CPU cores, fully utilizing the machine's computational resources.


Conclusion

Understanding the difference between threading and multiprocessing is crucial for writing efficient Python programs. Here’s a quick recap:

  • Use threading for I/O-bound tasks where your program spends a lot of time waiting for resources.
  • Use multiprocessing for CPU-bound tasks to maximize performance through parallel execution.

Knowing when to use which approach can lead to significant performance improvements and efficient use of resources.

以上是了解 Python 中的线程和多重处理:综合指南的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

Rimworld Odyssey温度指南和Gravtech
1 个月前 By Jack chen
初学者的Rimworld指南:奥德赛
1 个月前 By Jack chen
PHP变量范围解释了
4 周前 By 百草
撰写PHP评论的提示
3 周前 By 百草
在PHP中评论代码
3 周前 By 百草

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Laravel 教程
1604
29
PHP教程
1509
276
Python类可以有多个构造函数吗? Python类可以有多个构造函数吗? Jul 15, 2025 am 02:54 AM

Yes,aPythonclasscanhavemultipleconstructorsthroughalternativetechniques.1.Usedefaultargumentsinthe__init__methodtoallowflexibleinitializationwithvaryingnumbersofparameters.2.Defineclassmethodsasalternativeconstructorsforclearerandscalableobjectcreati

python for Loop范围 python for Loop范围 Jul 14, 2025 am 02:47 AM

在Python中,使用for循环配合range()函数是控制循环次数的常见方式。1.当明确知道循环次数或需按索引访问元素时使用;2.range(stop)从0到stop-1,range(start,stop)从start到stop-1,range(start,stop,step)加入步长;3.注意range不包含结束值,且在Python3返回可迭代对象而非列表;4.可通过list(range())转换为列表,倒序时用负步长。

用于量子机学习的Python 用于量子机学习的Python Jul 21, 2025 am 02:48 AM

要入门量子机器学习(QML),首选工具是Python,需安装PennyLane、Qiskit、TensorFlowQuantum或PyTorchQuantum等库;接着通过运行示例熟悉流程,如使用PennyLane构建量子神经网络;然后按照数据集准备、数据编码、构建参数化量子线路、经典优化器训练等步骤实现模型;实战中应避免一开始就追求复杂模型,关注硬件限制,采用混合模型结构,并持续参考最新文献和官方文档以跟进发展。

从Python中的Web API访问数据 从Python中的Web API访问数据 Jul 16, 2025 am 04:52 AM

使用Python调用WebAPI获取数据的关键在于掌握基本流程和常用工具。1.使用requests发起HTTP请求是最直接的方式,通过get方法获取响应并用json()解析数据;2.对于需要认证的API,可通过headers添加token或key;3.需检查响应状态码,推荐使用response.raise_for_status()自动处理异常;4.面对分页接口,可通过循环依次请求不同页面并加入延时避免频率限制;5.处理返回的JSON数据时需根据结构提取信息,复杂数据可用pandas转换为Data

python一行,如果还有 python一行,如果还有 Jul 15, 2025 am 01:38 AM

Python的onelineifelse是三元操作符,写法为xifconditionelsey,用于简化简单的条件判断。它可用于变量赋值,如status="adult"ifage>=18else"minor";也可用于函数中直接返回结果,如defget_status(age):return"adult"ifage>=18else"minor";虽然支持嵌套使用,如result="A"i

成品python大片在线观看入口 python免费成品网站大全 成品python大片在线观看入口 python免费成品网站大全 Jul 23, 2025 pm 12:36 PM

本文为您精选了多个顶级的Python“成品”项目网站与高水平“大片”级学习资源入口。无论您是想寻找开发灵感、观摩学习大师级的源代码,还是系统性地提升实战能力,这些平台都是不容错过的宝库,能帮助您快速成长为Python高手。

python如果还有示例 python如果还有示例 Jul 15, 2025 am 02:55 AM

写Python的ifelse语句关键在于理解逻辑结构与细节。1.基础结构是if条件成立执行一段代码,否则执行else部分,else可选;2.多条件判断用elif实现,顺序执行且一旦满足即停止;3.嵌套if用于进一步细分判断,建议不超过两层;4.简洁场景可用三元表达式替代简单ifelse。注意缩进、条件顺序及逻辑完整性,才能写出清晰稳定的判断代码。

python for循环逐行读取文件 python for循环逐行读取文件 Jul 14, 2025 am 02:47 AM

使用for循环逐行读取文件是一种高效处理大文件的方法。1.基本用法是通过withopen()打开文件并自动管理关闭,结合forlineinfile遍历每一行,line.strip()可去除换行符和空格;2.若需记录行号,可用enumerate(file,start=1)让行号从1开始;3.处理非ASCII文件时应指定encoding参数如utf-8,以避免编码错误。这些方法简洁实用,适用于大多数文本处理场景。

See all articles