国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

python綜合學習二之多進程

gityuan / 2150人閱讀

摘要:本節(jié)講學習的多進程。和之前的的不同點是丟向的函數(shù)有返回值,而的沒有返回值。所以接下來讓我們來看下這兩個進程是否會出現(xiàn)沖突。

</>復制代碼

  1. 本節(jié)講學習Python的多進程。
一、多進程和多線程比較

多進程 Multiprocessing 和多線程 threading 類似, 他們都是在 python 中用來并行運算的. 不過既然有了 threading, 為什么 Python 還要出一個 multiprocessing 呢? 原因很簡單, 就是用來彌補 threading 的一些劣勢, 比如在 threading 教程中提到的GIL.

使用 multiprocessing 也非常簡單, 如果對 threading 有一定了解的朋友, 你們的享受時間就到了. 因為 python 把 multiprocessing 和 threading 的使用方法做的幾乎差不多. 這樣我們就更容易上手. 也更容易發(fā)揮你電腦多核系統(tǒng)的威力了!

二、添加進程Process

</>復制代碼

  1. import multiprocessing as mp
  2. import threading as td
  3. def job(a,d):
  4. print("aaaaa")
  5. t1 = td.Thread(target=job,args=(1,2))
  6. p1 = mp.Process(target=job,args=(1,2))
  7. t1.start()
  8. p1.start()
  9. t1.join()
  10. p1.join()

從上面的使用對比代碼可以看出,線程和進程的使用方法相似。

使用

在運用時需要添加上一個定義main函數(shù)的語句

</>復制代碼

  1. if __name__=="__main__":

完整的應用代碼:

</>復制代碼

  1. # -*- coding:utf-8 -*-
  2. """
  3. @author: Corwien
  4. @file: process_test.py
  5. @time: 18/8/26 01:12
  6. """
  7. import multiprocessing as mp
  8. def job(a, d):
  9. print a, d
  10. if __name__ == "__main__":
  11. p1 = mp.Process(target=job, args=(1, 2))
  12. p1.start()
  13. p1.join()

運行環(huán)境要在terminal環(huán)境下,可能其他的編輯工具會出現(xiàn)運行結束后沒有打印結果,在terminal中的運行后打印的結果為:

</>復制代碼

  1. ? baseLearn python ./process/process_test.py
  2. 1 2
  3. ? baseLearn
三、存儲進程輸出Queue

Queue的功能是將每個核或線程的運算結果放在隊里中, 等到每個線程或核運行完畢后再從隊列中取出結果, 繼續(xù)加載運算。原因很簡單, 多線程調用的函數(shù)不能有返回值, 所以使用Queue存儲多個線程運算的結果

process_queue.py

</>復制代碼

  1. # -*- coding:utf-8 -*-
  2. """
  3. @author: Corwien
  4. @file: process_queue.py
  5. @time: 18/8/26 01:12
  6. """
  7. import multiprocessing as mp
  8. # 定義一個被多線程調用的函數(shù),q 就像一個隊列,用來保存每次函數(shù)運行的結果
  9. def job(q):
  10. res = 0
  11. for i in range(1000):
  12. res += i + i**2 + i**3
  13. q.put(res) #queue
  14. if __name__ == "__main__":
  15. q = mp.Queue()
  16. p1 = mp.Process(target=job, args=(q,))
  17. p2 = mp.Process(target=job, args=(q,))
  18. # 分別啟動、連接兩個線程
  19. p1.start()
  20. p2.start()
  21. p1.join()
  22. p2.join()
  23. # 上面是分兩批處理的,所以這里分兩批輸出,將結果分別保存
  24. res1 = q.get()
  25. res2 = q.get()
  26. print res1,res2

打印輸出結果:

</>復制代碼

  1. ? python ./process/process_queue.py
  2. 249833583000 249833583000
四、進程池

進程池就是我們將所要運行的東西,放到池子里,Python會自行解決多進程的問題。

1、導入多進程模塊

首先import multiprocessing 和定義job()

</>復制代碼

  1. import multiprocessing as mp
  2. def job(x):
  3. return x*x
2、進程池Pool()和map()

然后我們定義一個Pool

</>復制代碼

  1. pool = mp.Pool()

有了池子之后,就可以讓池子對應某一個函數(shù),我們向池子里丟數(shù)據(jù),池子就會返回函數(shù)返回的值。 Pool和之前的Process的不同點是丟向Pool的函數(shù)有返回值,而Process沒有返回值。

接下來用map()獲取結果,在map()中需要放入函數(shù)和需要迭代運算的值,然后它會自動分配給CPU核,返回結果

</>復制代碼

  1. res = pool.map(job, range(10))

讓我們來運行一下

</>復制代碼

  1. def multicore():
  2. pool = mp.Pool()
  3. res = pool.map(job, range(10))
  4. print(res)
  5. if __name__ == "__main__":
  6. multicore()

完成代碼:

</>復制代碼

  1. # -*- coding:utf-8 -*-
  2. """
  3. @author: Corwien
  4. @file: process_queue.py
  5. @time: 18/8/26 01:12
  6. """
  7. import multiprocessing as mp
  8. def job(x):
  9. return x*x # 注意這里的函數(shù)有return返回值
  10. def multicore():
  11. pool = mp.Pool()
  12. res = pool.map(job, range(10))
  13. print(res)
  14. if __name__ == "__main__":
  15. multicore()

執(zhí)行結果:

</>復制代碼

  1. ? baseLearn python ./process/process_pool.py
  2. [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
3、自定義核數(shù)量

我們怎么知道Pool是否真的調用了多個核呢?我們可以把迭代次數(shù)增大些,然后打開CPU負載看下CPU運行情況

打開CPU負載(Mac):活動監(jiān)視器 > CPU > CPU負載(單擊一下即可)

Pool默認大小是CPU的核數(shù),我們也可以通過在Pool中傳入processes參數(shù)即可自定義需要的核數(shù)量

</>復制代碼

  1. def multicore():
  2. pool = mp.Pool(processes=3) # 定義CPU核數(shù)量為3
  3. res = pool.map(job, range(10))
  4. print(res)
4、apply_async()

Pool除了map()外,還有可以返回結果的方式,那就是apply_async().

apply_async()只能傳遞一個值,它只會放入一個核進行運算,但是傳入值時要注意是可迭代的,所以在傳入值后需要加逗號, 同時需要用get()方法獲取返回值

</>復制代碼

  1. def multicore():
  2. pool = mp.Pool()
  3. res = pool.map(job, range(10))
  4. print(res)
  5. res = pool.apply_async(job, (2,))
  6. # 用get獲得結果
  7. print(res.get())

運行結果;

</>復制代碼

  1. [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # map()
  2. 4 # apply_async()
總結

Pool默認調用是CPU的核數(shù),傳入processes參數(shù)可自定義CPU核數(shù)

map() 放入迭代參數(shù),返回多個結果

apply_async()只能放入一組參數(shù),并返回一個結果,如果想得到map()的效果需要通過迭代

五、共享內存shared memory

這節(jié)我們學習如何定義共享內存。只有用共享內存才能讓CPU之間有交流。

Shared Value

我們可以通過使用Value數(shù)據(jù)存儲在一個共享的內存表中。

</>復制代碼

  1. import multiprocessing as mp
  2. value1 = mp.Value("i", 0)
  3. value2 = mp.Value("d", 3.14)

其中di參數(shù)用來設置數(shù)據(jù)類型的,d表示一個雙精浮點類型 double,i表示一個帶符號的整型。

Type code C Type Python Type Minimum size in bytes
"b" signed char int 1
"B" unsigned char int 1
"u" Py_UNICODE Unicode character 2
"h" signed short int 2
"H" unsigned short int 2
"i" signed int int 2
"I" unsigned int int 2
"l" signed long int 4
"L" unsigned long int 4
"q" signed long long int 8
"Q" unsigned long long int 8
"f" float float 4
"d" double float 8
Shared Array

在Python的 mutiprocessing 中,有還有一個Array類,可以和共享內存交互,來實現(xiàn)在進程之間共享數(shù)據(jù)。

</>復制代碼

  1. array = mp.Array("i", [1, 2, 3, 4])

這里的Array和numpy中的不同,它只能是一維的,不能是多維的。同樣和Value 一樣,需要定義數(shù)據(jù)形式,否則會報錯。 我們會在后一節(jié)舉例說明這兩種的使用方法.

錯誤形式

</>復制代碼

  1. array = mp.Array("i", [[1, 2], [3, 4]]) # 2維list
  2. """
  3. TypeError: an integer is required
  4. """
六、進程鎖Lock 不加進程鎖

讓我們看看沒有加進程鎖時會產生什么樣的結果。

</>復制代碼

  1. # -*- coding:utf-8 -*-
  2. """
  3. @author: Corwien
  4. @file: process_no_lock.py
  5. @time: 18/8/26 09:22
  6. """
  7. import multiprocessing as mp
  8. import time
  9. def job(v, num):
  10. for _ in range(5):
  11. time.sleep(0.5) # 暫停0.5秒,讓輸出效果更明顯
  12. v.value += num # v.value獲取共享變量值
  13. print(v.value)
  14. def multicore():
  15. v = mp.Value("i", 0) # 定義共享變量
  16. p1 = mp.Process(target=job, args=(v, 1))
  17. p2 = mp.Process(target=job, args=(v, 4)) # 設定不同的number看如何搶奪內存
  18. p1.start()
  19. p2.start()
  20. p1.join()
  21. p2.join()
  22. if __name__ == "__main__":
  23. multicore()

在上面的代碼中,我們定義了一個共享變量v,兩個進程都可以對它進行操作。 在job()中我們想讓v每隔0.1秒輸出一次累加num的結果,但是在兩個進程p1p2 中設定了不同的累加值。所以接下來讓我們來看下這兩個進程是否會出現(xiàn)沖突。

結果打?。?/p>

</>復制代碼

  1. ? baseLearn python ./process/process_no_lock.py
  2. 1
  3. 5
  4. 9
  5. 9
  6. 13
  7. 13
  8. 17
  9. 17
  10. 18
  11. 18
  12. ? baseLearn

我們可以看到,進程1和進程2在相互著使用共享內存v

加進程鎖

為了解決上述不同進程搶共享資源的問題,我們可以用加進程鎖來解決。

首先需要定義一個進程鎖

</>復制代碼

  1. l = mp.Lock() # 定義一個進程鎖

然后將進程鎖的信息傳入各個進程中

</>復制代碼

  1. p1 = mp.Process(target=job, args=(v,1,l)) # 需要將Lock傳入
  2. p2 = mp.Process(target=job, args=(v,3,l))

job()中設置進程鎖的使用,保證運行時一個進程的對鎖內內容的獨占

</>復制代碼

  1. def job(v, num, l):
  2. l.acquire() # 鎖住
  3. for _ in range(5):
  4. time.sleep(0.1)
  5. v.value += num # v.value獲取共享內存
  6. print(v.value)
  7. l.release() # 釋放

全部代碼:

</>復制代碼

  1. # -*- coding:utf-8 -*-
  2. """
  3. @author: Corwien
  4. @file: process_lock.py
  5. @time: 18/8/26 09:22
  6. """
  7. import multiprocessing as mp
  8. import time
  9. def job(v, num, l):
  10. l.acquire() # 鎖住
  11. for _ in range(5):
  12. time.sleep(0.5) # 暫停0.5秒,讓輸出效果更明顯
  13. v.value += num # v.value獲取共享變量值
  14. print(v.value)
  15. l.release() # 釋放
  16. def multicore():
  17. l = mp.Lock() # 定義一個進程鎖
  18. v = mp.Value("i", 0) # 定義共享變量
  19. p1 = mp.Process(target=job, args=(v, 1, l)) # 需要將lock傳入
  20. p2 = mp.Process(target=job, args=(v, 4, l)) # 設定不同的number看如何搶奪內存
  21. p1.start()
  22. p2.start()
  23. p1.join()
  24. p2.join()
  25. if __name__ == "__main__":
  26. multicore()

運行一下,讓我們看看是否還會出現(xiàn)搶占資源的情況:

結果打?。?/p>

</>復制代碼

  1. ? baseLearn python ./process/process_lock.py
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5
  7. 9
  8. 13
  9. 17
  10. 21
  11. 25

顯然,進程鎖保證了進程p1的完整運行,然后才進行了進程p2的運行

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/42314.html

相關文章

  • python綜合學習之多線程

    摘要:如下面的例子,在學習線程時,將文件名命名為腳本完全正常沒問題,結果報下面的錯誤。最大的問題就是的多線程程序并不能利用多核的優(yōu)勢比如一個使用了多個線程的計算密集型程序只會在一個單上面運行。 本文記錄學習Python遇到的問題和一些常用用法,注本開發(fā)環(huán)境的Python版本為2.7。 一、python文件命名 在python文件命名時,一定要注意不能和系統(tǒng)默認的模塊名沖突,否則會報錯。如下面...

    cjie 評論0 收藏0
  • 零基礎如何學爬蟲技術

    摘要:楚江數(shù)據(jù)是專業(yè)的互聯(lián)網數(shù)據(jù)技術服務,現(xiàn)整理出零基礎如何學爬蟲技術以供學習,。本文來源知乎作者路人甲鏈接楚江數(shù)據(jù)提供網站數(shù)據(jù)采集和爬蟲軟件定制開發(fā)服務,服務范圍涵蓋社交網絡電子商務分類信息學術研究等。 楚江數(shù)據(jù)是專業(yè)的互聯(lián)網數(shù)據(jù)技術服務,現(xiàn)整理出零基礎如何學爬蟲技術以供學習,http://www.chujiangdata.com。 第一:Python爬蟲學習系列教程(來源于某博主:htt...

    KunMinX 評論0 收藏0
  • 云數(shù)據(jù)的三大安全威脅

    摘要:對云數(shù)據(jù)安全來說,也是一樣的。行業(yè)在保護企業(yè)內部數(shù)據(jù)安全方面,已經有幾十年的經驗了。行業(yè)對云數(shù)據(jù)安全的經驗還太少。據(jù)統(tǒng)計,類似這樣的用戶誤操作占數(shù)據(jù)損失的三分之一到三分之二之多。由于云應用的日益復雜,以及行業(yè)還缺乏關于云安全的統(tǒng)一的標準。 任何一個驚悚電影的愛好者都會告訴你, 真正的恐怖在于你無法預計什么時候,怎么樣的災難會發(fā)生。 對云數(shù)據(jù)安全來說,也是一樣的。 IT行業(yè)在保護企業(yè)內部數(shù)據(jù)安...

    sydMobile 評論0 收藏0
  • Python爬蟲學習路線

    摘要:以下這些項目,你拿來學習學習練練手。當你每個步驟都能做到很優(yōu)秀的時候,你應該考慮如何組合這四個步驟,使你的爬蟲達到效率最高,也就是所謂的爬蟲策略問題,爬蟲策略學習不是一朝一夕的事情,建議多看看一些比較優(yōu)秀的爬蟲的設計方案,比如說。 (一)如何學習Python 學習Python大致可以分為以下幾個階段: 1.剛上手的時候肯定是先過一遍Python最基本的知識,比如說:變量、數(shù)據(jù)結構、語法...

    liaoyg8023 評論0 收藏0
  • Python爬蟲利器二之Beautiful Soup的用法

    摘要:官方解釋如下提供一些簡單的式的函數(shù)用來處理導航搜索修改分析樹等功能。廢話不多說,我們來試一下吧安裝目前已經停止開發(fā),推薦在現(xiàn)在的項目中使用,不過它已經被移植到了,也就是說導入時我們需要。 上一節(jié)我們介紹了正則表達式,它的內容其實還是蠻多的,如果一個正則匹配稍有差池,那可能程序就處在永久的循環(huán)之中,而且有的小伙伴們也對寫正則表達式的寫法用得不熟練,沒關系,我們還有一個更強大的工具,叫Be...

    cjie 評論0 收藏0

發(fā)表評論

0條評論

gityuan

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<