歡迎大家關注我,一起學習~
multiprocessing和threading:
多線程 threading:計算機同一時間還是隻能處理一個線程
多核 multiprocessing:現在計算機都有多核處理器,將任務分給多個核來處理,他們有單獨的運算空間和計算能力,避免了多線程的劣勢。
導入包:
定義一個被線程和進程調用的函數
創建進程和線程
Queue功能:
Queue的功能是將每個核或線程的運算結果放在隊裡中, 等到每個線程或核運行完畢後再從隊列中取出結果, 繼續加載運算。原因很簡單, 多線程調用的函數不能有返回值, 所以使用Queue存儲多個線程運算的結果
定義一個被多線程調用的函數,q就像一個隊列,用來保存每次函數運行的結果
主函數:
效率比較:多線程、多進程、普通的消耗時間;
實際時間對比:
運行時間是 多進程 < 普通 < 多線程
進程池就是我們將所要運行的東西,放到池子裡,Python會自行解決多進程的問題。
導入包並定義函數:
有了池子之後,就可以讓池子對應某一個函數,向池子裡輸入數據,池子就會返回函數返回的值。
Pool和之前的Process的不同點是丟向Pool的函數有返回值,而Process的沒有返回值。
接下來用map()獲取結果,在map()中需要放入函數和需要迭代運算的值,然後它會自動分配給CPU所有核,返回結果。
除了map()函數,Pool還有apply_async()函數可以返回結果。apply_async()中只能傳遞一個值,只會放入一個核進行運算,傳入值時要注意是可迭代的,所以在傳入值後需要加逗號。
如何用apply_async()輸出多個迭代呢?多傳入幾個值試試~
合併代碼:
可以看出在apply用迭代器的得到的結果和用map得到的結果是一樣的
總結
1. Pool默認調用是CPU的核數,傳入processes參數可自定義CPU核數
2. map() 放入迭代參數,返回多個結果
3. apply_async()只能放入一組參數,並返回一個結果,如果想得到map()的效果需要通過迭代。
只有用共享內存才能讓CPU之間有交流。
Shared Value:(多線程中global value)
多進程,即使傳入global 變量,多進程中也無法交流,我們可以通過使用Value數據存儲在一個共享的內存表中。
Shared Array:(僅僅是一個一維列表)
這裡的Array和numpy中的不同,它只能是一維的,不能是多維的。
同樣和Value 一樣,需要定義數據形式,否則會報錯。
參考數據形式
各參數代表的數據類型
進程鎖的運用:使進程之間不會互相干擾
不加進程鎖
在上面的代碼中,我們定義了一個共享變量v,兩個進程都可以對它進行操作。 在job()中我們想讓v每隔0.1秒輸出一次累加num的結果,但是在兩個進程p1和p2 中設定了不同的累加值。所以接下來讓我們來看下這兩個進程是否會出現衝突。
運行一下:
145891213161720
我們可以看到,進程1和進程2在相互搶著使用共享內存v。
加進程鎖
為了解決上述不同進程搶共享資源的問題,我們可以用加進程鎖來解決。
首先需要定義一個進程鎖
然後將進程鎖的信息傳入各個進程中
在job()中設置進程鎖的使用,保證運行時一個進程的對鎖內內容的獨佔
完整代碼:
運行一下,讓我們看看是否還會出現搶佔資源的情況:
12345811141720
顯然,進程鎖保證了進程p1的完整運行,然後才進行了進程p2的運行
參考自:莫煩python https://morvanzhou.github.io/tutorials/python-basic/multiprocessing/
為了更方便管理文章,同名微信公眾號已經上線,喜歡使用微信的朋友們,歡迎大家關注!
閱讀更多 AI深度學習求索 的文章