網站首頁 編程語言 正文
為什么要引入線程池
如果在程序中經常要用到線程,頻繁的創建和銷毀線程會浪費很多硬件資源,
所以需要把線程和任務分離。線程可以反復利用,省去了重復創建的麻煩。
在 Process 類中,我們必須顯式地創建流程。但是,Pool 類更方便,您不必手動管理它。創建池對象的語法是 ?multiprocessing.Pool(processes, initializer, initargs, maxtasksperchild, context)?
? 。所有參數都是可選的。
- processes 表示您要創建的工作進程的數量。默認值通過 os.cpu_count() 獲取。
- initializer第二個初始化器參數是一個用于初始化的函數。
- initargs 是傳遞給它的參數。
-
maxtasksperchild
表示分配給每個子進程的任務數。在完成該數量的任務之后,該進程將被一個新的工作進程替換。指定它的好處是任何未使用的資源都將被釋放。如果未提供任何內容,則只要池存在,進程就會存在。
import time from multiprocessing import Pool def square(x): print(f"start process:{x}") square = x * x print(f"square {x}:{square}") time.sleep(1) print(f"end process:{x}") if __name__ == "__main__": starttime = time.time() pool = Pool() pool.map(square, range(0, 5)) pool.close() endtime = time.time() print(f"Time taken {endtime-starttime} seconds")
結果為:
start process:0
start process:1
square 1:1
square 0:0
end process:1
start process:2
end process:0
start process:3
square 2:4
square 3:9
end process:3
end process:2
start process:4
square 4:16
end process:4
Time taken 3.0474610328674316 seconds
在這里,我們從多處理模塊中導入 Pool 類。在主函數中,我們創建了一個 Pool 類的對象。 pool.map() 將我們想要并行化的函數和一個可迭代的函數作為參數。它在可迭代的每個項目上運行給定的函數。它還接受一個可選的 chunksize 參數,它將可迭代對象拆分為等于給定大小的塊,并將每個塊作為單獨的任務傳遞。 pool.close() 用于拒絕新任務。
我們可以看到花費的時間大約是 3 秒。
?pool.imap()?
? 與 ?pool.map()?
? 方法幾乎相同。不同的是,每個項目的結果都是在準備好后立即收到的,而不是等待所有項目都完成。此外, ?map()?
? 方法將可迭代對象轉換為列表(如果不是)。但是, ?imap()?
? 方法沒有。
來看下一個例子:
import time from multiprocessing import Pool def square(x): print(f"start process {x}") square = x * x time.sleep(1) print(f"end process {x}") return square if __name__ == "__main__": pool = Pool() a = pool.map(square, range(0, 5)) print(a)
運行結果:
start process 0
start process 1
end process 0
start process 2
end process 1
start process 3
end process 2
start process 4
end process 3
end process 4
[0, 1, 4, 9, 16]
from concurrent.futures import ThreadPoolExecutor def say_hello(): print("Hello") executor = ThreadPoolExecutor(50) for i in range(0, 10): executor.submit(say_hello)
練習
利用 Python 多線程模擬商品秒殺過程,不可以出現超買和超賣的情況。假設A商品有50件參與秒殺活動,10分鐘秒殺自動結束。
- kill_total 商品總數
- kill_num 成功搶購數
- kill_flag 有效標志位
- kill_user 成功搶購的用戶ID
from redis_db import pool import redis import random from concurrent.futures import ThreadPoolExecutor s = set() while True: if len(s) == 1000: break num = random.randint(10000, 100000) s.add(num) print(s) con = redis.Redis( connection_pool=pool ) try: con.delete("kill_total", "kill_num", "kill_flag", "kill_user") con.set("kill_total", 50) con.set("kill_num", 0) con.set("kill_flag", 1) con.expire("kill_flag", 600) except Exception as e: print(e) finally: del con executor = ThreadPoolExecutor(200) def buy(): connection = redis.Redis( connection_pool=pool ) pipline = connection.pipline() try: if connection.exists("kill_flag") == 1: pipline.watch("kill_num", "kill_user") total = pipline.get("kill_total") num = int(pipline.get("kill_num").decode("utf-8")) if num < total: pipline.multi() pipline.incr("kill_num") user_id = s.pop() pipline.rpush("kill_user", user_id) pipline.execute() except Exception as e: print(e) finally: if "pipline" in dir(): pipline.reset() del connection for i in range(0, 1000): executor.submit(buy) print("秒殺活動已經結束")
原文鏈接:https://blog.51cto.com/yuzhou1su/5200609
相關推薦
- 2022-09-03 python四則運算表達式求值示例詳解_python
- 2022-09-02 詳解Flutter手游操縱桿移動的原理與實現_Android
- 2023-08-01 前端傳遞對象數組,后端使用list接收并解析
- 2022-06-10 SQL?Server使用導出向導功能_MsSql
- 2022-11-11 C#中的Hashtable?類使用詳解_C#教程
- 2022-04-03 python中如何利用matplotlib畫多個并列的柱狀圖_python
- 2022-03-31 C#判斷語句的表達式樹實現_C#教程
- 2022-05-19 Nginx+Windows搭建域名訪問環境的操作方法_nginx
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支