在當今快節奏的數位環境中,對於開發人員和資料科學家來說,有效完成計算困難的任務至關重要。幸運的是,由於其適應性和廣泛的生態系統,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中文網其他相關文章!