Python多線程與線程池(python線程池ThreadPoolExecutor)concurrent.futures高級別異步執行封裝

文章目錄

  • Python多線程與線程池
    • 一、Python多線程
      • 1.1 線程簡介
      • 1.2 Python中的多線程
      • 1.3 GIL限制
    • 二、線程池
      • 2.1 Python中的線程池
    • 三、代碼分析
    • 四、參考資料

Python多線程與線程池

一、Python多線程

在進行復雜的計算或處理大量數據時,可以通過創建多個線程來同時執行多個任務,從而提高程序的執行效率。這種技術稱為多線程編程。

1.1 線程簡介

線程是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以并發多個線程,每條線程并行執行不同的任務。
在這里插入圖片描述

1.2 Python中的多線程

Python中的threading模塊提供了對線程的支持。使用threading模塊創建線程,直接從threading.Thread繼承,然后重寫__init__方法和run方法。

import threadingclass MyThread(threading.Thread):def __init__(self, n):super(MyThread, self).__init__()self.n = ndef run(self):print('running task', self.n)t1 = MyThread(1)
t2 = MyThread(2)t1.start()
t2.start()

在這里插入圖片描述

1.3 GIL限制

由于Python解釋器設計中的全局解釋器鎖(Global Interpreter Lock,GIL)的存在,使得Python的多線程并不能利用多核優勢。GIL是計算機程序設計語言解釋器用于同步線程的工具,使得任何時刻只有一個線程在執行,即使在多核CPU平臺上,Python的線程也無法同時執行。

在這里插入圖片描述

二、線程池

線程池是一種基于池化思想管理線程的工具。在開始任務時不再重新創建新的線程,而是直接從線程池中獲取一個空閑線程來執行。如果線程池中沒有空閑線程,新的任務就會等待(排隊),直到有線程空閑。當任務執行完畢后,線程并不立即銷毀,而是返回線程池等待下次被利用。

2.1 Python中的線程池

Python的concurrent.futures模塊提供了高級別的異步執行封裝,包括線程池ThreadPoolExecutor和進程池ProcessPoolExecutor,它們都是Executor的子類。

from concurrent.futures import ThreadPoolExecutordef func(n):print(n)with ThreadPoolExecutor(max_workers=4) as executor:executor.map(func, range(1,5))

其中max_workers參數表示線程池中最多可以同時運行的線程數量。

在這里插入圖片描述

三、代碼分析

import requests
from requests.models import PreparedRequest
import json
import concurrent.futuresdef get_score_models(url):url_score = "https://bizapi.csdn.net/trends/api/v1/get-article-score"headers = {"accept": "application/json, text/plain, */*","x-ca-key": "203930474","x-ca-nonce": "22cd11a0-760a-45c1-8089-14e53123a852","x-ca-signature": "RaEczPkQ22Ep/k9/AI737gCtn8qX67CV/uGdhQiPIdQ=","x-ca-signature-headers": "x-ca-key,x-ca-nonce","x-ca-signed-content-type": "multipart/form-data"}data = {"url": url}response = send_request(url_score, data, headers)data1 = response.json()score_model = data1["data"]return score_modeldef send_request(url, data, headers):session = requests.Session()prepared_request = PreparedRequest()prepared_request.prepare(method='POST', url=url,headers=headers, data=data)return session.send(prepared_request)def process_article_json(article):# score_model = get_score_models(article['article_url'])score_model = get_score_models(article['url'])article['article_score'] = score_model['score']print(article["url"])return articleif __name__ == '__main__':# 讀取articles.json文件with open('articles.json', 'r') as f:articles = json.load(f)# 創建一個 ThreadPoolExecutor 實例,max_workers 表示線程池中最多可以同時運行的線程數量with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:# 使用 map 函數將 process_article_json 應用到每個元素,并在多線程環境下并行處理processed_articles = list(executor.map(process_article_json, articles))# 保存處理后的結果到新的JSON文件output_file = 'processed_articles.json'with open(output_file, 'w') as f:json.dump(processed_articles, f, ensure_ascii=False, indent=4)

import requests
from requests.models import PreparedRequest
import json
import concurrent.futures
def get_score_models(url):
url_score = “https://bizapi.csdn.net/trends/api/v1/get-article-score”
headers = {
“accept”: “application/json, text/plain, /”,
“x-ca-key”: “203930474”,
“x-ca-nonce”: “22cd11a0-760a-45c1-8089-14e53123a852”,
“x-ca-signature”: “RaEczPkQ22Ep/k9/AI737gCtn8qX67CV/uGdhQiPIdQ=”,
“x-ca-signature-headers”: “x-ca-key,x-ca-nonce”,
“x-ca-signed-content-type”: “multipart/form-data”
}
data = {“url”: url}
response = send_request(url_score, data, headers)
data1 = response.json()
score_model = data1[“data”]
return score_model
def send_request(url, data, headers):
session = requests.Session()
prepared_request = PreparedRequest()
prepared_request.prepare(method=‘POST’, url=url,
headers=headers, data=data)
return session.send(prepared_request)
def process_article_json(article):
# score_model = get_score_models(article[‘article_url’])
score_model = get_score_models(article[‘url’])
article[‘article_score’] = score_model[‘score’]
print(article[“url”])
return article
if name == ‘main’:
# 讀取articles.json文件
with open(‘articles.json’, ‘r’) as f:
articles = json.load(f)
# 創建一個 ThreadPoolExecutor 實例,max_workers 表示線程池中最多可以同時運行的線程數量
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
# 使用 map 函數將 process_article_json 應用到每個元素,并在多線程環境下并行處理
processed_articles = list(executor.map(process_article_json, articles))
# 保存處理后的結果到新的JSON文件
output_file = ‘processed_articles.json’
with open(output_file, ‘w’) as f:
json.dump(processed_articles, f, ensure_ascii=False, indent=4)

在這里插入圖片描述

以上給出的代碼片段主要涉及到的是線程池的使用。具體來說,首先從一個名為articles.json的文件中讀取文章信息,然后利用線程池并發地獲取每篇文章的評分,并將評分添加到文章信息中,最后將處理后的文章信息保存到新的JSON文件。

代碼的主要部分如下:

with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:processed_articles = list(executor.map(process_article_json, articles))

在這里插入圖片描述

這里,首先創建了一個ThreadPoolExecutor實例,并設置最大并發線程數為5。然后使用executor.map()函數將process_article_json函數應用到articles列表的每個元素上,這樣就可以在多線程環境下并行處理每篇文章了。由于executor.map()函數返回的是一個迭代器,因此需要用list()函數將其轉換為列表。

這種方式可以有效地提高處理大量文章信息的效率,特別是當獲取文章評分的過程涉及到網絡請求等I/O操作時,通過線程池并發處理可以顯著減少總的處理時間。

在這里插入圖片描述

四、參考資料

  • Python官方文檔:threading — Thread-based parallelism
  • Python官方文檔:concurrent.futures — Launching parallel tasks
  • Python線程池使用示例
  • Python多線程與GIL
  • 3. 爬取自己CSDN博客列表(分頁查詢)(網站反爬蟲策略,需要在代碼中添加合適的請求頭User-Agent,否則response返回空)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/38381.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/38381.shtml
英文地址,請注明出處:http://en.pswp.cn/news/38381.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Sentinel規則持久化

首先 Sentinel 控制臺通過 API 將規則推送至客戶端并更新到內存中,接著注冊的寫數據源會將新的規則保存到本地的文件中。 示例代碼: 1.編寫處理類 //規則持久化 public class FilePersistence implements InitFunc {Value("spring.application:n…

云原生k8s---資源限制、探針

目錄 一:資源限制 1、資源限制原因 2、Pod 和 容器 的資源請求和限制 3、CPU 資源單位 4、內存 資源單位 5、事例 (1)事例一 (2)事例二 二:重啟策略 1、重啟策略模式 2、事例 三:探針…

Win10提醒事項如何打開?電腦上如何添加日程提醒?

有不少上班族表示自己在日常辦公時,經常會忘記一些重要的事情,例如領導安排給自己的任務、會議安排、項目截止日期等。為了避免自己忘記工作事項,很多人都想要在電腦上設置提醒事項或添加日程提醒。那么Win10提醒事項如何打開呢?P…

Golang 中的 archive/zip 包詳解(一):實現 ZIP 壓縮與解壓

Golang 中的 archive/zip 包用于處理 ZIP 格式的壓縮文件,提供了一系列用于創建、讀取和解壓縮 ZIP 格式文件的函數和類型,使用起來非常方便。 實現壓縮功能 1、首先需要創建一個 zip 文件。 zip 文件也是一個文件,首先需要創建一個基礎的…

[Leetcode] [Tutorial] 多維動態規劃(未完待續)

文章目錄 62. 不同路徑Solution 62. 不同路徑 一個機器人位于一個 m ? * ? n 網格的左上角 (起始點在下圖中標記為 “Start” )。 機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角。 問總共有多少條不同的路徑? 示例…

【electron】electron項目創建的方式:

文章目錄 【1】npm init quick-start/electron(推薦)【2】 克隆倉庫,快速啟動【3】 通過腳手架搭建項目【4】 手動創建項目 【Electron官網】https://www.electronjs.org/zh/docs/latest/api/app 【1】npm init quick-start/electron&#xf…

Excelize Go語言操作 Office Excel文檔基礎庫

Excelize 是 Go 語言編寫的用于操作 Office Excel 文檔基礎庫,基于 ECMA-376,ISO/IEC 29500 國際標準。可以使用它來讀取、寫入由 Microsoft Excel? 2007 及以上版本創建的電子表格文檔。支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多種文檔格式&#xf…

微信小程序實現左滑刪除

一、效果 二、代碼 實現思路使用的是官方提供的 movable-area:注意點,需要設置其高度,否則會出現列表內容重疊的現象。由于movable-view需要向右移動,左滑的時候給刪除控件展示的空間,故 movable-area 需要左移 left:…

Android Gradle Plug-in(AGP ) 的對應關系

AGP 和 Gradle 版本的對應關系 Android Gradle 插件版本說明 | Android 開發者 | Android Developers 插件版本所需的最低 Gradle 版本8.18.08.08.07.47.57.37.47.27.3.37.17.27.07.04.2.06.7.1 舊版 插件版本所需的 Gradle 版本4.1.06.54.0.06.1.13.6.0 - 3.6.45.6.4…

sqlloader學習筆記

INFILE的用法 1)模糊導入多個數據的文件。 可以在文件名中使用通配符。 星號 (*) 表示復數字符,問號 (?) 表示單個字符。 INFILE emp*.dat INFILE m?emp.dat 2)如果不需要導入數據…

jQuery EasyUI datagrid 無記錄時,增加“暫無數據“提示

我們只需要在onLoadSuccess中添加如下代碼&#xff1a; if (data.total 0) {var body $(this).data().datagrid.dc.body2;body.find(table tbody).append(<tr><td width" body.width() " style"height: 35px; text-align: center;"><h…

C語言學習之封裝自定義函數,實現atoi函數功能

實例要求&#xff1a;atoi函數的功能是把字符串轉成整型數值并輸出&#xff1b;把字符串"123456"轉換成數值123456 &#xff0c;并返回數值&#xff1b;函數名&#xff1a; int myatoi(char *str);實例分析&#xff1a; 1.自定義的封裝函數類型是整型&#xff0c;…

在阿里云Linux服務器上部署MySQL數據庫流程

阿里云百科分享在阿里云Linux服務器上部署MySQL數據庫流程&#xff0c;MySQL是一個關系型數據庫管理系統&#xff0c;常用于LAMP和LNMP等網站場景中。本教程介紹如何在Linux系統ECS實例上安裝、配置以及遠程訪問MySQL數據庫。 目錄 背景信息 Alibaba Cloud Linux 2/3、CentO…

上傳excel文件

文件上傳&#xff0c;其實就是用el-upload組件來實現上傳&#xff0c;只是換了樣式&#xff0c;和圖片上傳一樣 <el-form-item label"選擇文件"><el-input placeholder"請選擇文件" v-model"form.file" disabled style"width: 45…

java 使用log4j顯示到界面和文件 并格式化

1.下載log4j jar包https://dlcdn.apache.org/logging/log4j/2.20.0/apache-log4j-2.20.0-bin.zip 2. 我只要到核心包 &#xff0c;看需要 sources是源碼包&#xff0c;可以看到說明。在IDEA里先加入class jar后&#xff0c;再雙擊這個class jar包或或右鍵選Navigate ,Add ,…

android.system.ErrnoException: open failed: EPERM (Operation not permitted)

android 10(Q)開始增加了沙盒機制&#xff0c;不能直接把文件保存到/sdcard目錄下&#xff0c;只能保存到APP專屬目錄下&#xff1b;AndroidManifest.xml在標簽下增加屬性【android:requestLegacyExternalStorage“true”】可以暫時保存到/sdcard路徑下&#xff0c;但是Android…

Revit SDK 介紹:PanelSchedule 配電盤明細表

前言 這個例子介紹 Revit 的配電盤明細表&#xff0c;PanelSchedule。Revit 的電器專業在國內用的并不是十分廣泛&#xff0c;但從功能上來說還是比較完整的。 內容 這個例子里有三個命令&#xff1a; PanelScheduleExport - 導出配電盤明細表InstanceViewCreation - 創建配…

【0基礎學爬蟲】爬蟲基礎之網絡請求庫的使用

大數據時代&#xff0c;各行各業對數據采集的需求日益增多&#xff0c;網絡爬蟲的運用也更為廣泛&#xff0c;越來越多的人開始學習網絡爬蟲這項技術&#xff0c;K哥爬蟲此前已經推出不少爬蟲進階、逆向相關文章&#xff0c;為實現從易到難全方位覆蓋&#xff0c;特設【0基礎學…

【Visual Studio Code】--- Win11 C盤爆滿 修改 Code 插件數據和緩存的保存路徑

Win11 C盤爆滿 修改 Code 插件數據和緩存的保存路徑 一、概述二、修改 Code 插件數據和緩存的保存路徑 一、概述 一個好的文章能夠幫助開發者完成更便捷、更快速的開發。書山有路勤為徑&#xff0c;學海無涯苦作舟。我是秋知葉i、期望每一個閱讀了我的文章的開發者都能夠有所成…

領航優配:EFT交易是什么意思?

EFT買賣是一種電子資金搬運買賣方法&#xff0c;EFT代表電子資金搬運&#xff0c;將現金從一個銀行賬戶搬運到另一個銀行賬戶。盡管這種買賣方法已經存在了幾十年&#xff0c;但隨著技能的開展&#xff0c;越來越多的人開始使用它。 從技能視點&#xff0c;EFT買賣是經過計算機…