Python3 加C# 並發編程!強強組合!會產生什麽樣的化學反應?
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:為當前進程實例的別名
- p.is_alive() 判斷進程實例p是否還在執行
- 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之後,被暫停後會在線程池裏面繼續運行
再看一個場景:比如一個耗時操作,我需要指定它的超時時間:
異步這塊簡單回顧就不說了,留兩個擴展,你們自行探討:
- 進度方面的可以使用 IProgress<T>,就當留個作業自己摸索下吧~
- 使用了異步之後盡量避免使用 task.Wait or task.Result,這樣可以避免死鎖
Task其他新特征去官網看看吧,引入到此為止了。
2.並行編程(Parallel)
這個其實出來很久了,現在基本上都是用 PLinq比較多點,主要就是:
- 數據並行:重點在處理數據(eg:聚合)
- 任務並行:重點在執行任務(每個任務塊盡可能獨立,越獨立效率越高)
數據並行
以前都是 Parallel.ForEach這麽用,現在和Linq結合之後非常方便 .AsParallel()就OK了
說很抽象看個簡單案例:
當然了,如果你就是對順序有要求可以使用: .AsOrdered()
不使用並行:(稍微多了點,CPU越密集差距越大)
- 499999500000
- real
- 0m0.103s
- user
- 0m0.092s
- sys
- 0m0.021s
其實聚合有一個通用方法,可以支持復雜的聚合:(以上面sum為例)
- .
- Aggregate
- (
- seed
- :
- 0
- ,
- func
- :(
- sum
- ,
- item
- )=>
- sum
- +
- item
- );
稍微擴展一下,PLinq也是支持取消的, .WithCancellation(CancellationToken)
Token的用法和上面一樣,就不復述了,如果需要和異步結合,一個 Task.Run就可以把並行任務交給線程池了
也可以使用Task的異步方法,設置超時時間,這樣PLinq超時了也就終止了
PLinq這麽方便,其實也是有一些小弊端的,比如它會直接最大程度的占用系統資源,可能會影響其他的任務,而傳統的Parallel則會動態調整
任務並行(並行調用)
這個PLinq好像沒有對應的方法,有新語法你可以說下,來舉個例子:
Python3 加C# 並發編程!強強組合!會產生什麽樣的化學反應?