1. 程式人生 > >Python3 加C# 並發編程!強強組合!會產生什麽樣的化學反應?

Python3 加C# 並發編程!強強組合!會產生什麽樣的化學反應?

不能 python3.3 await 可能 傳統 img assert linu 暫停

1.進程篇

官方文檔:https://docs.python.org/3/library/multiprocessing.html

1.1.進程(Process)

Python的進程創建非常方便,看個案例:(這種方法通用,fork只適用於Linux系)

進群:548377875 即可獲取數十套PDF哦!

技術分享圖片

其他參數可以參考源碼 or 文檔,貼一下源碼的 init方法:

def__init__(self,group=None,target=None,name=None,args=(),kwargs={},*,daemon=None)

擴展: name:為當前進程實例的別名

  1. p.is_alive() 判斷進程實例p是否還在執行
  2. p.terminate() 終止進程(發 SIGTERM信號)

上面的案例如果用OOP來實現就是這樣:(如果不指定方法,默認調Run方法)

技術分享圖片

1.1.源碼拓展

現在說說裏面的一些門道(只像用的可以忽略)

新版本的封裝可能多層,這時候可以看看Python3.3.X系列(這個算是Python3早期版本了,很多代碼都暴露出來,比較明了直觀)

技術分享圖片

技術分享圖片

關於斷言的簡單說明:(別泛濫)

如果條件為真,它什麽都不做,反之它觸發一個帶可選錯誤信息的AssertionError

技術分享圖片

1.2.進程池

多個進程就不需要自己手動去管理了,有Pool來幫你完成,先看個案例:

技術分享圖片

圖示:(join可以指定超時時間,eg: p.join(1))

技術分享圖片

調用 join()之前必須先調用 close(),調用 close()之後就不能繼續添加新的 Process了


1.3.源碼拓展

驗證一下Pool的默認大小是CPU的核數,看源碼:

multiprocessing.pool.py

技術分享圖片

來看個例子:(和JQ很像)

技術分享圖片

技術分享圖片

大家這麽急,那就先推Net的,Python過幾天再推

其實逆天現在Coding已經是80%變成Python了,20%才是Net,也不確定是否一直在Net界幹下去,所以只能盡可能的在說新知識的同時,盡量把腦子裏面Net相關的內容教給大家,萬一跨行業也算對得起大家的厚愛了(這個我從來不強求,反正什麽編程語言都一樣,順其自然~)

NetCore並發編程

示例代碼:https://github.com/lotapp/BaseCode/tree/master/netcore/4_Concurrency

先簡單說下概念(其實之前也有說,所以簡說下):

技術分享圖片

技術分享圖片

然後補充說下Task異常的問題,當你await的時候如果有異常會拋出,在第一個await處捕獲處理即可

如果 async和 await就是理解不了的可以這樣想: async就是為了讓 await生效(為了向後兼容)

技術分享圖片

一個async方法被await調用後,當它恢復運行時就會回到原來的上下文中運行。

如果你的Task不再需要上下文了可以使用: task.ConfigureAwait(false),eg:寫個日記還要啥上下文?

逆天的建議是:在核心代碼裏面一種使用 ConfigureAwait,用戶頁面相關代碼,不需要上下文的加上

其實如果有太多await在上下文裏恢復那也是比較卡的,使用 ConfigureAwait之後,被暫停後會在線程池裏面繼續運行

再看一個場景:比如一個耗時操作,我需要指定它的超時時間:

技術分享圖片

異步這塊簡單回顧就不說了,留兩個擴展,你們自行探討:

  1. 進度方面的可以使用 IProgress<T>,就當留個作業自己摸索下吧~
  2. 使用了異步之後盡量避免使用 task.Wait or task.Result,這樣可以避免死鎖

Task其他新特征去官網看看吧,引入到此為止了。


2.並行編程(Parallel)

這個其實出來很久了,現在基本上都是用 PLinq比較多點,主要就是:

  1. 數據並行:重點在處理數據(eg:聚合)
  2. 任務並行:重點在執行任務(每個任務塊盡可能獨立,越獨立效率越高)

數據並行

以前都是 Parallel.ForEach這麽用,現在和Linq結合之後非常方便 .AsParallel()就OK了

說很抽象看個簡單案例:

技術分享圖片

當然了,如果你就是對順序有要求可以使用: .AsOrdered()

技術分享圖片

不使用並行:(稍微多了點,CPU越密集差距越大)

  1. 499999500000
  2. real
  3. 0m0.103s
  4. user
  5. 0m0.092s
  6. sys
  7. 0m0.021s

其實聚合有一個通用方法,可以支持復雜的聚合:(以上面sum為例)

  1. .
  2. Aggregate
  3. (
  4. seed
  5. :
  6. 0
  7. ,
  8. func
  9. :(
  10. sum
  11. ,
  12. item
  13. )=>
  14. sum
  15. +
  16. item
  17. );

稍微擴展一下,PLinq也是支持取消的, .WithCancellation(CancellationToken)

Token的用法和上面一樣,就不復述了,如果需要和異步結合,一個 Task.Run就可以把並行任務交給線程池了

也可以使用Task的異步方法,設置超時時間,這樣PLinq超時了也就終止了

PLinq這麽方便,其實也是有一些小弊端的,比如它會直接最大程度的占用系統資源,可能會影響其他的任務,而傳統的Parallel則會動態調整


任務並行(並行調用)

這個PLinq好像沒有對應的方法,有新語法你可以說下,來舉個例子:

技術分享圖片

技術分享圖片

Python3 加C# 並發編程!強強組合!會產生什麽樣的化學反應?