激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

香港云服务器
服務器之家 - 腳本之家 - Python - 用一個開源工具實現多線程 Python 程序的可視化

用一個開源工具實現多線程 Python 程序的可視化

2021-03-31 23:04Linux中國Tian Gao Python

VizTracer 是一個追蹤和可視化 Python 程序的工具,對日志、調試和剖析很有幫助。盡管它對單線程、單任務程序很好用,但它在并發程序中的實用性是它的獨特之處。

用一個開源工具實現多線程 Python 程序的可視化

VizTracer 可以跟蹤并發的 Python 程序,以幫助記錄、調試和剖析。

并發是現代編程中必不可少的一部分,因為我們有多個核心,有許多需要協作的任務。然而,當并發程序不按順序運行時,就很難理解它們。對于工程師來說,在這些程序中發現 bug 和性能問題不像在單線程、單任務程序中那么容易。

在 Python 中,你有多種并發的選擇。最常見的可能是用 threading 模塊的多線程,用subprocess 和 multiprocessing 模塊的多進程,以及最近用 asyncio 模塊提供的 async 語法。在 VizTracer 之前,缺乏分析使用了這些技術程序的工具。

VizTracer 是一個追蹤和可視化 Python 程序的工具,對日志、調試和剖析很有幫助。盡管它對單線程、單任務程序很好用,但它在并發程序中的實用性是它的獨特之處。

嘗試一個簡單的任務

 

從一個簡單的練習任務開始:計算出一個數組中的整數是否是質數并返回一個布爾數組。下面是一個簡單的解決方案:

  1. def is_prime(n):
  2. for i in range(2, n):
  3. if n % i == 0:
  4. return False
  5. return True
  6.  
  7. def get_prime_arr(arr):
  8. return [is_prime(elem) for elem in arr]

試著用 VizTracer 以單線程方式正常運行它:

  1. if __name__ == "__main__":
  2. num_arr = [random.randint(100, 10000) for _ in range(6000)]
  3. get_prime_arr(num_arr)
  1. viztracer my_program.py

 

用一個開源工具實現多線程 Python 程序的可視化

Running code in a single thread

調用堆棧報告顯示,耗時約 140ms,大部分時間花在 get_prime_arr 上。

 

用一個開源工具實現多線程 Python 程序的可視化

call-stack report

這只是在數組中的元素上一遍又一遍地執行 is_prime 函數。

這是你所期望的,而且它并不有趣(如果你了解 VizTracer 的話)。

試試多線程程序

 

試著用多線程程序來做:

  1. if __name__ == "__main__":
  2.     num_arr = [random.randint(100, 10000) for i in range(2000)]
  3.     thread1 = Thread(target=get_prime_arr, args=(num_arr,))
  4.     thread2 = Thread(target=get_prime_arr, args=(num_arr,))
  5.     thread3 = Thread(target=get_prime_arr, args=(num_arr,))
  6.  
  7.     thread1.start()
  8.     thread2.start()
  9.     thread3.start()
  10.  
  11.     thread1.join()
  12.     thread2.join()
  13.     thread3.join()

為了配合單線程程序的工作負載,這就為三個線程使用了一個 2000 元素的數組,模擬了三個線程共享任務的情況。

 

用一個開源工具實現多線程 Python 程序的可視化

Multi-thread program

如果你熟悉 Python 的全局解釋器鎖(GIL),就會想到,它不會再快了。由于開銷太大,花了 140ms 多一點的時間。不過,你可以觀察到多線程的并發性:

 

用一個開源工具實現多線程 Python 程序的可視化

Concurrency of multiple threads

當一個線程在工作(執行多個 is_prime 函數)時,另一個線程被凍結了(一個 is_prime 函數);后來,它們進行了切換。這是由于 GIL 的原因,這也是 Python 沒有真正的多線程的原因。它可以實現并發,但不能實現并行。

用多進程試試

 

要想實現并行,辦法就是 multiprocessing 庫。下面是另一個使用 multiprocessing 的版本:

  1. if __name__ == "__main__":
  2.     num_arr = [random.randint(100, 10000) for _ in range(2000)]
  3.    
  4.     p1 = Process(target=get_prime_arr, args=(num_arr,))
  5.     p2 = Process(target=get_prime_arr, args=(num_arr,))
  6.     p3 = Process(target=get_prime_arr, args=(num_arr,))
  7.  
  8.     p1.start()
  9.     p2.start()
  10.     p3.start()
  11.  
  12.     p1.join()
  13.     p2.join()
  14.     p3.join()

要使用 VizTracer 運行它,你需要一個額外的參數:

  1. viztracer --log_multiprocess my_program.py

 

用一個開源工具實現多線程 Python 程序的可視化

Running with extra argument

整個程序在 50ms 多一點的時間內完成,實際任務在 50ms 之前完成。程序的速度大概提高了三倍。

為了和多線程版本進行比較,這里是多進程版本:

 

用一個開源工具實現多線程 Python 程序的可視化

Multi-process version

在沒有 GIL 的情況下,多個進程可以實現并行,也就是多個 is_prime 函數可以并行執行。

不過,Python 的多線程也不是一無是處。例如,對于計算密集型和 I/O 密集型程序,你可以用睡眠來偽造一個 I/O 綁定的任務:

  1. def io_task():
  2.     time.sleep(0.01)

在單線程、單任務程序中試試:

  1. if __name__ == "__main__":
  2.     for _ in range(3):
  3.         io_task()

 

用一個開源工具實現多線程 Python 程序的可視化

I/O-bound single-thread, single-task program

整個程序用了 30ms 左右,沒什么特別的。

現在使用多線程:

  1. if __name__ == "__main__":
  2.     thread1 = Thread(target=io_task)
  3.     thread2 = Thread(target=io_task)
  4.     thread3 = Thread(target=io_task)
  5.  
  6.     thread1.start()
  7.     thread2.start()
  8.     thread3.start()
  9.  
  10.     thread1.join()
  11.     thread2.join()
  12.     thread3.join()

 

用一個開源工具實現多線程 Python 程序的可視化

I/O-bound multi-thread program

程序耗時 10ms,很明顯三個線程是并發工作的,這提高了整體性能。

用 asyncio 試試

 

Python 正在嘗試引入另一個有趣的功能,叫做異步編程。你可以制作一個異步版的任務:

  1. import asyncio
  2.  
  3. async def io_task():
  4.     await asyncio.sleep(0.01)
  5.  
  6. async def main():
  7.     t1 = asyncio.create_task(io_task())
  8.     t2 = asyncio.create_task(io_task())
  9.     t3 = asyncio.create_task(io_task())
  10.  
  11.     await t1
  12.     await t2
  13.     await t3
  14.  
  15. if __name__ == "__main__":
  16.     asyncio.run(main())

由于 asyncio 從字面上看是一個帶有任務的單線程調度器,你可以直接在它上使用 VizTracer:

 

用一個開源工具實現多線程 Python 程序的可視化

VizTracer with asyncio

依然花了 10ms,但顯示的大部分函數都是底層結構,這可能不是用戶感興趣的。為了解決這個問題,可以使用 --log_async 來分離真正的任務:

  1. viztracer --log_async my_program.py

 

用一個開源工具實現多線程 Python 程序的可視化

Using --log_async to separate tasks

現在,用戶任務更加清晰了。在大部分時間里,沒有任務在運行(因為它唯一做的事情就是睡覺)。有趣的部分是這里:

 

用一個開源工具實現多線程 Python 程序的可視化

Graph of task creation and execution

這顯示了任務的創建和執行時間。Task-1 是 main() 協程,創建了其他任務。Task-2、Task-3、Task-4 執行 io_task 和 sleep 然后等待喚醒。如圖所示,因為是單線程程序,所以任務之間沒有重疊,VizTracer 這樣可視化是為了讓它更容易理解。

為了讓它更有趣,可以在任務中添加一個 time.sleep 的調用來阻止異步循環:

  1. async def io_task():
  2.     time.sleep(0.01)
  3.     await asyncio.sleep(0.01)

 

用一個開源工具實現多線程 Python 程序的可視化

time.sleep call

程序耗時更長(40ms),任務填補了異步調度器中的空白。

這個功能對于診斷異步程序的行為和性能問題非常有幫助。

看看 VizTracer 發生了什么?

 

通過 VizTracer,你可以在時間軸上查看程序的進展情況,而不是從復雜的日志中想象。這有助于你更好地理解你的并發程序。

VizTracer 是開源的,在 Apache 2.0 許可證下發布,支持所有常見的操作系統(Linux、macOS 和 Windows)。你可以在 VizTracer 的 GitHub 倉庫中了解更多關于它的功能和訪問它的源代碼。

原文地址:https://linux.cn/article-13253-1.html

延伸 · 閱讀

精彩推薦
737
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 国产91九色视频 | 日韩美香港a一级毛片 | 国产精品.com | 一区二区三区四区视频在线观看 | 九九热精品视频在线播放 | 久久免费视频7 | 嫩草91在线 | 成年人国产视频 | 日韩中文字幕一区二区三区 | 国产精品一区在线看 | 日韩999 | av在线不卡免费 | 黑人一级片视频 | 久久久久久片 | 末成年女av片一区二区 | 欧美一级黄视频 | 成年人在线免费播放视频 | 悠悠成人资源亚洲一区二区 | 毛片久久| 87成人免费看片 | 亚洲精品成人久久久 | 色人阁五月天 | 视频一区二区中文字幕 | 国产精品成人av片免费看最爱 | 久久久线视频 | 日本成人一区二区三区 | 日本中文字幕高清 | 欧美一级全黄 | 久久精品欧美电影 | 成人福利网 | 国产精品久久久久久久四虎电影 | 精品国产一区二区三区成人影院 | 亚洲导航深夜福利涩涩屋 | fc2国产成人免费视频 | www.com超碰 | 欧美不卡在线 | 日日操夜夜操视频 | 黄色毛片视频在线观看 | 毛片免费在线观看 | 插插操| 一区二区三区在线观看国产 |