網站首頁 編程語言 正文
使用 asyncio 包處理并發
asyncio包:使用事件循環驅動的協程實現并發。
線程與協程的對比
'\ thinking' 旋轉等待效果
In [1]: import threading In [2]: import itertools In [3]: import time,sys In [4]: class Signal: # 定義一個簡單的可變對象;go 屬性 從外部控制線程 ...: go = True In [5]: def spin(msg,signal): ...: w,flush = sys.stdout.write,sys.stdout.flush ...: for char in itertools.cycle('|/-\\'): # 從序列中反復不斷的生成元素 ...: status = char + ' ' + msg ...: w(status) ...: flush() ...: w('\x08' * len(status)) # 退格鍵:\x08 文本動畫的訣竅所在 ...: time.sleep(1) ...: if not signal.go: ...: break ...: w(' ' * len(status) + '\x08' * len(status)) In [6]: def slow(): ...: time.sleep(3) ...: return 42 In [9]: def super(): ...: signal = Signal() ...: sp = threading.Thread(target=spin,args=('thinking',signal)) ...: print('============') ...: sp.start() ...: res = slow() ...: signal.go = False ...: sp.join() ...: return res
注意:Python 沒有提供終止線程的 API ,這是有意為之的。若想關閉線程,必須給線程發送消息。這里用的是 signal.go 屬性。干凈的規則的退出。
適合 asyncio API 的協程:
1 定義體必須使用?yield from
?,而不能使用?yield
2 協程要由調用方驅動,并由調用方通過?yield from
?調用
3 或者把協程傳給 asyncio 包中的某個函數,比如 asyncio.async()
4 @asyncio.coroutine 裝飾器應該用在協程上
asyncio 實現 動畫效果
In [1]: import asyncio In [3]: import itertools In [4]: import sys # 交給 asyncio 處理的協程需要使用該裝飾器裝飾。這不是強制要求,但是強烈建議這么做。 In [5]: @asyncio.coroutine ...: def spin(msg): # 不需要多線程的關閉參數 ...: w,flush = sys.stdout.write, sys.stdout.flush ...: for char in itertools.cycle('|/-\\'): ...: status = char + ' ' + msg ...: w(status) ...: flush() ...: w('\x08' * len(status)) ...: try: ...: yield from asyncio.sleep(.1) # 不會阻塞事件循環 # spin 函數蘇醒后,取消請求 異常,退出循環 ...: except asyncio.CancelledError: ...: break ...: write(' ' * len(status) + '\x08' * len(status)) ...: In [6]: @asyncio.coroutine ...: def slow(): # 把控制權交給主循環,休眠結束后,結束這個協程 ...: yield from asyncio.sleep(3) ...: return 42 ...: In [9]: @asyncio.coroutine ...: def sup(): # asyncio 排定spin協程的運行時間,封裝成一個 Task對象 sp ...: sp = asyncio.async(spin('thinking!')) ...: print('spin obj:',sp) # sup 也是協程,因此,可以使用 yield from 驅動 slow() ...: res = yield from slow() sp.cancel() ...: return res ...: In [10]: def main(): ...: loop = asyncio.get_event_loop() ...: res = loop.run_until_complete(sup()) ...: loop.close() ...: print('answer:',res) ...: In [11]: main() D:\python36\Scripts\ipython:3: DeprecationWarning: asyncio.async() function is deprecated, use ensure_future() spin obj: <Task pending coro=<spin() running at <ipython-input-5-0304845f34e1>:1>> answer: 42!
除非想阻塞主線程,從而凍結事件循環或整個應用,否則不要在 asyncio 協程中使用 time.sleep() 。如果協程需要一段時間內什么也不做,應該使用 yield from asyncio.sleep() 。
@asyncio.coroutine 裝飾器不是強制要求,但是強烈建議這么做,因為這樣能
1 把協程凸顯出來,有助于調試。
2 如果還未產出值,協程就被垃圾回收了(意味著有操作未完成,因此有可能是個缺陷),那就可以發出警告了。
3 這個裝飾器不會預激協程。
原文鏈接:https://blog.csdn.net/m0_72557783/article/details/128188439
相關推薦
- 2022-03-29 Python函數裝飾器的使用詳解_python
- 2022-07-06 使用pandas兩列轉換成字典的健和值_python
- 2022-09-04 Go語言中的函數詳解_Golang
- 2022-10-27 LyScript實現指令查詢功能的示例代碼_python
- 2022-03-19 詳解C語言結構體的定義和使用_C 語言
- 2023-01-15 React報錯Too?many?re-renders解決_React
- 2022-10-29 CSS實現單行、多行文本溢出顯示省略號的實現方法
- 2022-04-11 K8S部署Kafka界面管理工具(kafkamanager)方法詳解_云其它
- 最近更新
-
- 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同步修改后的遠程分支