在当今快节奏的数字环境中,对于开发人员和数据科学家来说,有效完成计算困难的任务至关重要。幸运的是,由于其适应性和广泛的生态系统,Python提供了强大的并行处理能力。我们可以通过将困难的问题分解为更小、更易管理的活动,并同时进行处理,从而获得大幅度的性能提升。
Python 的并行处理功能使我们能够利用可用的计算机资源更快、更有效地进行网页抓取、科学模拟和数据分析等活动。在这篇文章中,我们将通过 Python 并行处理开始一段旅程。我们将研究许多方法,包括多处理、异步编程和多线程,并学习如何有效地使用它们来绕过系统中的性能障碍。加入我们,让我们认识到 Python 并行处理的全部威力,并达到性能和生产力的新高度。
将作业拆分为较小的子任务并在多个处理器或内核上同时运行它们称为并行处理。并行处理可以通过有效地利用可用的计算资源来显着减少程序的总执行时间。异步编程、多处理和多线程只是 Python 提供的几种并行处理方法。
使用多线程的方法,许多线程在同一个进程内同时运行,共享同一块内存。可以使用Python的threading模块很容易地实现多线程。然而,在Python中使用多线程可能不会对CPU密集型操作产生加速效果,因为全局解释器锁(GIL)只允许一个线程同时执行Python字节码。然而,多线程对于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的multiprocessing模块提供了一个高级接口来实现多进程。多进程适用于CPU密集型任务,因为每个进程在独立的Python解释器中运行,避免了GIL多线程限制。
在下面的代码中使用了多进程。一旦池类生成了一组工作进程,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]
通过利用非阻塞操作,异步编程实现了I/O密集型进程的高效执行。由于有了asyncio包,Python可以使用协程、事件循环和futures来创建异步代码。随着在线应用和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 交互和网页抓取。异步编程最大限度地减少了 I/O 操作的等待时间,确保了响应能力和可扩展性。
Python 的并行处理能力为提高需要复杂计算的任务的效率提供了机会。无论您选择使用多线程、多处理还是异步编程,Python 都提供了必要的工具和模块来有效利用并发性。通过理解活动的性质并选择适当的技术,您可以最大限度地发挥并行处理的优势并缩短执行时间。因此,继续探索并充分利用 Python 的并行性来创建更快、更高效的应用程序。
以上是在Python中的并行处理的详细内容。更多信息请关注PHP中文网其他相关文章!