国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python中的并發編程實例

2019-11-25 18:20:20
字體:
來源:轉載
供稿:網友

一、簡介

  我們將一個正在運行的程序稱為進程。每個進程都有它自己的系統狀態,包含內存狀態、打開文件列表、追蹤指令執行情況的程序指針以及一個保存局部變量的調用棧。通常情況下,一個進程依照一個單序列控制流順序執行,這個控制流被稱為該進程的主線程。在任何給定的時刻,一個程序只做一件事情。

  一個程序可以通過Python庫函數中的os或subprocess模塊創建新進程(例如os.fork()或是subprocess.Popen())。然而,這些被稱為子進程的進程卻是獨立運行的,它們有各自獨立的系統狀態以及主線程。因為進程之間是相互獨立的,因此它們同原有的進程并發執行。這是指原進程可以在創建子進程后去執行其它工作。

  雖然進程之間是相互獨立的,但是它們能夠通過名為進程間通信(IPC)的機制進行相互通信。一個典型的模式是基于消息傳遞,可以將其簡單地理解為一個純字節的緩沖區,而send()或recv()操作原語可以通過諸如管道(pipe)或是網絡套接字(network socket)等I/O通道傳輸或接收消息。還有一些IPC模式可以通過內存映射(memory-mapped)機制完成(例如mmap模塊),通過內存映射,進程可以在內存中創建共享區域,而對這些區域的修改對所有的進程可見。

  多進程能夠被用于需要同時執行多個任務的場景,由不同的進程負責任務的不同部分。然而,另一種將工作細分到任務的方法是使用線程。同進程類似,線程也有其自己的控制流以及執行棧,但線程在創建它的進程之內運行,分享其父進程的所有數據和系統資源。當應用需要完成并發任務的時候線程是很有用的,但是潛在的問題是任務間必須分享大量的系統狀態。

  當使用多進程或多線程時,操作系統負責調度。這是通過給每個進程(或線程)一個很小的時間片并且在所有活動任務之間快速循環切換來實現的,這個過程將CPU時間分割為小片段分給各個任務。例如,如果你的系統中有10個活躍的進程正在執行,操作系統將會適當的將十分之一的CPU時間分配給每個進程并且循環地在十個進程之間切換。當系統不止有一個CPU核時,操作系統能夠將進程調度到不同的CPU核上,保持系統負載平均以實現并行執行。

  利用并發執行機制寫的程序需要考慮一些復雜的問題。復雜性的主要來源是關于同步和共享數據的問題。通常情況下,多個任務同時試圖更新同一個數據結構會造成臟數據和程序狀態不一致的問題(正式的說法是資源競爭的問題)。為了解決這個問題,需要使用互斥鎖或是其他相似的同步原語來標識并保護程序中的關鍵部分。舉個例子,如果多個不同的線程正在試圖同時向同一個文件寫入數據,那么你需要一個互斥鎖使這些寫操作依次執行,當一個線程在寫入時,其他線程必須等待直到當前線程釋放這個資源。

Python中的并發編程

  Python長久以來一直支持不同方式的并發編程,包括線程、子進程以及其他利用生成器(generator function)的并發實現。

  Python在大部分系統上同時支持消息傳遞和基于線程的并發編程機制。雖然大部分程序員對線程接口更為熟悉,但是Python的線程機制卻有著諸多的限制。Python使用了內部全局解釋器鎖(GIL)來保證線程安全,GIL同時只允許一個線程執行。這使得Python程序就算在多核系統上也只能在單個處理器上運行。Python界關于GIL的爭論盡管很多,但在可預見的未來卻沒有將其移除的可能。

  Python提供了一些很精巧的工具用于管理基于線程和進程的并發操作。即使是簡單地程序也能夠使用這些工具使得任務并發進行從而加快運行速度。subprocess模塊為子進程的創建和通信提供了API。這特別適合運行與文本相關的程序,因為這些API支持通過新進程的標準輸入輸出通道傳送數據。signal模塊將UNIX系統的信號量機制暴露給用戶,用以在進程之間傳遞事件信息。信號是異步處理的,通常有信號到來時會中斷程序當前的工作。信號機制能夠實現粗粒度的消息傳遞系統,但是有其他更可靠的進程內通訊技術能夠傳遞更復雜的消息。threading模塊為并發操作提供了一系列高級的,面向對象的API。Thread對象們在一個進程內并發地運行,分享內存資源。使用線程能夠更好地擴展I/O密集型的任務。multiprocessing模塊同threading模塊類似,不過它提供了對于進程的操作。每個進程類是真實的操作系統進程,并且沒有共享內存資源,但multiprocessing模塊提供了進程間共享數據以及傳遞消息的機制。通常情況下,將基于線程的程序改為基于進程的很簡單,只需要修改一些import聲明即可。

Threading模塊示例

  以threading模塊為例,思考這樣一個簡單的問題:如何使用分段并行的方式完成一個大數的累加。

import threading class SummingThread(threading.Thread):  def __init__(self, low, high):    super(SummingThread, self).__init__()    self.low = low    self.high = high    self.total = 0   def run(self):    for i in range(self.low, self.high):      self.total += i thread1 = SummingThread(0, 500000)thread2 = SummingThread(500000, 1000000)thread1.start() # This actually causes the thread to runthread2.start()thread1.join() # This waits until the thread has completedthread2.join()# At this point, both threads have completedresult = thread1.total + thread2.totalprint(result)

自定義Threading類庫

  我寫了一個易于使用threads的小型Python類庫,包含了一些有用的類和函數。

關鍵參數:

  * do_threaded_work

主站蜘蛛池模板: 临清市| 庆阳市| 定州市| 黑山县| 双桥区| 伽师县| 元氏县| 曲阜市| 平塘县| 田林县| 遂川县| 扎鲁特旗| 额尔古纳市| 额济纳旗| 郎溪县| 湘潭市| 雷州市| 珠海市| 永修县| 安陆市| 禹城市| 长春市| 霍州市| 罗江县| 洪泽县| 射洪县| 南江县| 峨眉山市| 达孜县| 丹凤县| 双江| 新竹县| 阿荣旗| 拉孜县| 嘉祥县| 青河县| 望江县| 浮梁县| 阆中市| 新邵县| 大邑县|