Python 并行处理

Python 并行处理

在如今快节奏的数字环境中,对于开发人员和数据科学家来说,高效地完成计算困难的任务至关重要。幸运的是,由于其适应性和广泛的生态系统,Python提供了强大的并行处理能力。通过将困难的问题分解为更小、更易处理的任务,并并行执行它们,我们可以获得显著的性能改进。

Python的并行处理功能使我们能够更快速、更有效地处理诸如网络爬虫、科学模拟和数据分析等活动,利用可用的计算资源。在这篇文章中,让我们通过Python并行处理的旅程。我们将探讨多种方法,包括多进程、异步编程和多线程,学习如何有效地使用它们来克服系统性能限制。加入我们,发现Python并行处理的全部潜力,实现更高的性能和生产力。

理解并行处理

将一个任务分解为更小的子任务,然后在多个处理器或核心上并行运行它们,这被称为并行处理。通过有效利用可用的计算资源,并行处理可以显著减少程序的总执行时间。Python提供了异步编程、多进程和多线程等多种并行处理方法。

Python中的多线程

使用多线程的方法,多个线程在同一个进程中并行运行,共享同一块内存。Python的线程模块可以很容易地实现多线程。然而,由于全局解释器锁(GIL)一次只允许一个线程执行Python字节码,所以多线程在CPU限制的操作中可能不会带来速度提升。然而,对于I/O限制的任务,多线程是很有用的,因为它允许线程在等待I/O操作完成时运行其他操作。

让我们看一个例子,我们使用多线程来下载许多网页:

示例

import threading import requests 

def download_page(url): 
    response = requests.get(url)    
print(f"Downloaded {url}") 

urls = [ 
    "https://example.com", 
    "https://google.com", 
    "https://openai.com" 
] 

threads = [] 
 for url in 
 urls: 
    thread = threading.Thread(target=download_page,
args=(url,))     thread.start()    threads.append(thread) 

for thread in threads: 
    thread.join()

输出

Downloaded https://example.com 
Downloaded https://google.com 
Downloaded https://openai.com

多个下载可以同时进行,多亏了上面的代码片段,它在各自的线程中下载每个URL。join()函数确保主线程在继续之前等待每个线程完成。

Python中的多进程

与多线程相比,多进程通过使用几个带有自己内存空间的进程提供真正的并行处理。Python的multiprocessing模块提供了一个实现多进程的高级接口。多进程适用于CPU密集型活动,因为每个进程在独立的Python解释器中运行,避免了GIL多线程限制。

下面的代码中使用了多进程。一旦pool类生成了一个工作进程池,map()方法将任务分配给可用进程。结果列表是结果的集合。

看看下面的例子,我们使用多进程来计算一个列表中每个整数的平方:

示例

import multiprocessing 

def square(number):    
return number ** 2 

numbers = [1, 2, 3, 4, 5] 

with multiprocessing.Pool() as pool: 
    results = pool.map(square, numbers) 

print(results)

输出

[1, 4, 9, 16, 25]

Python中的异步编程

通过利用非阻塞操作,异步编程可以高效执行I/O绑定的过程。由于asyncio包的存在,协程、事件循环和futures都可以用来创建Python中的异步代码。随着在线应用程序和API的流行,异步编程变得越来越重要。

下面的代码示例中,fetch_page()协程利用aiohttp异步获取网页。main()方法生成一个作业列表,并通过使用asyncio.gather()同时执行它们。要等待任务完成并接收结果,使用await关键字。

让我们来看一个使用asyncio和aiohttp异步获取多个网页的例子:

示例

import asyncio 
import aiohttp 

async def fetch_page(url):     async with aiohttp.ClientSession() as session:         async with session.get(url) as response: 
            return await response.text() 

async def main(): 
    urls = [ 
        "https://example.com", 
        "https://google.com", 
        "https://openai.com" 
    ] 

    tasks = [fetch_page(url) for url in urls]     pages = await asyncio.gather(*tasks)     
print(pages) 

asyncio.run(main())

输出

['<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta 
charset="utf-8" />\n    <meta http-equiv="Content-type"content="text/html; charset=utf-8" />\n    <meta name="viewport" content="width=device-width, initialscale=1" />\n    <style type="text/css">\n    body {\n        background-color: #f0f0f2;\n  margin: 0;\n        padding: 0;\n        font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n  padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (maxwidth: 700px) {\n        body {\n            background-color: #fff;\n        }\n        div {\n  width: auto;\n            margin: 0 auto;\n            border-radius: 0;\n            padding: 1em;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is for use in illustrative examples in documents. You may use this\n    domain in literature without prior coordination or asking for permission.</p>\n    <p><a href="https://www.iana.org/domains/example">More information...</a></p>\n</div>\n</body>\n</html>', '<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en"><head><meta content="Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for." name="description"><meta content="noodp" name="robots"><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"><meta content="/logos/doodles/2021/mom-
and-dad-6116550989716480.2-law.gif" itemprop="image"><link href="/logos/doodles/2021/mom-and-dad-6116550989716480.2-law.gif" rel="icon" type="image/gif"><title>Google</title><script nonce="sJwM0Ptp5a/whzxPtTD8Yw==">(function(){window.google={kEI:'cmKgYY37A7 K09QPhzKuACw',kEXPI:'1354557,1354612,1354620,1354954,1355090,1355493,13556
83,3700267,4029815,4031109,4032677,4036527,4038022,4043492,4045841,4048347,4
048490,4052469,4055589,4056520,4057177,4057696,4060329,4060798,4061854,4062 531,4064696,406 '

选择合适的方法

根据任务的具体内容,Python的并行处理技术有所不同。以下是一些指南,可以帮助您做出明智的决策:

对于I/O密集型活动,其中大部分执行时间都花在等待输入/输出操作上,多线程是合适的。它适用于下载文件、使用API和操作文件等任务。由于Python的全局解释器锁(GIL),多线程可能不会显著加快CPU密集型活动的速度。

另一方面,多进程非常适用于涉及大量计算的CPU密集型任务。它通过利用多个进程实现了真正的并行性,每个进程都有自己的内存空间,并且绕过了GIL的限制。然而,它会带来额外的开销,包括内存消耗和进程间通信。

对于涉及网络操作的I/O密集型活动,使用类似asyncio的库进行异步编程很有用。它利用非阻塞I/O操作,使作业可以继续进行,而不必等待每个操作完成。这种方法可以有效管理多个并发连接,适用于网络服务器开发、Web API交互和Web抓取。异步编程可以最大程度地减小I/O操作的等待时间,确保响应能力和可伸缩性。

结论

Python的并行处理能力为需要复杂计算的任务提供了增加效率的机会。无论您选择使用多线程、多进程还是异步编程,Python都提供了必要的工具和模块来有效地利用并发性。通过理解您的活动的性质并选择合适的技术,您可以最大限度地发挥并行处理的好处,缩短执行时间。因此,请放心地探索和利用Python的并行性,以实现更快、更高效的应用程序。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程