成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

python綜合學(xué)習(xí)二之多進(jìn)程

gityuan / 2155人閱讀

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

本節(jié)講學(xué)習(xí)Python的多進(jìn)程。
一、多進(jìn)程和多線程比較

多進(jìn)程 Multiprocessing 和多線程 threading 類似, 他們都是在 python 中用來(lái)并行運(yùn)算的. 不過(guò)既然有了 threading, 為什么 Python 還要出一個(gè) multiprocessing 呢? 原因很簡(jiǎn)單, 就是用來(lái)彌補(bǔ) threading 的一些劣勢(shì), 比如在 threading 教程中提到的GIL.

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

二、添加進(jìn)程Process
import multiprocessing as mp
import threading as td

def job(a,d):
    print("aaaaa")

t1 = td.Thread(target=job,args=(1,2))
p1 = mp.Process(target=job,args=(1,2))
t1.start()
p1.start()
t1.join()
p1.join()

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

使用

在運(yùn)用時(shí)需要添加上一個(gè)定義main函數(shù)的語(yǔ)句

if __name__=="__main__":

完整的應(yīng)用代碼:

# -*- coding:utf-8 -*-

"""
@author: Corwien
@file: process_test.py
@time: 18/8/26 01:12
"""

import multiprocessing as mp

def job(a, d):
    print a, d

if __name__ == "__main__":
    p1 = mp.Process(target=job, args=(1, 2))
    p1.start()
    p1.join()

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

?  baseLearn python ./process/process_test.py
1 2
?  baseLearn
三、存儲(chǔ)進(jìn)程輸出Queue

Queue的功能是將每個(gè)核或線程的運(yùn)算結(jié)果放在隊(duì)里中, 等到每個(gè)線程或核運(yùn)行完畢后再?gòu)年?duì)列中取出結(jié)果, 繼續(xù)加載運(yùn)算。原因很簡(jiǎn)單, 多線程調(diào)用的函數(shù)不能有返回值, 所以使用Queue存儲(chǔ)多個(gè)線程運(yùn)算的結(jié)果

process_queue.py

# -*- coding:utf-8 -*-

"""
@author: Corwien
@file: process_queue.py
@time: 18/8/26 01:12
"""

import multiprocessing as mp

# 定義一個(gè)被多線程調(diào)用的函數(shù),q 就像一個(gè)隊(duì)列,用來(lái)保存每次函數(shù)運(yùn)行的結(jié)果
def job(q):
    res = 0
    for i in range(1000):
        res += i + i**2 + i**3
    q.put(res)   #queue

if __name__ == "__main__":
    q = mp.Queue()
    p1 = mp.Process(target=job, args=(q,))
    p2 = mp.Process(target=job, args=(q,))

    # 分別啟動(dòng)、連接兩個(gè)線程
    p1.start()
    p2.start()
    p1.join()
    p2.join()

    # 上面是分兩批處理的,所以這里分兩批輸出,將結(jié)果分別保存
    res1 = q.get()
    res2 = q.get()

    print res1,res2

打印輸出結(jié)果:

? python ./process/process_queue.py
249833583000 249833583000
四、進(jìn)程池

進(jìn)程池就是我們將所要運(yùn)行的東西,放到池子里,Python會(huì)自行解決多進(jìn)程的問(wèn)題

1、導(dǎo)入多進(jìn)程模塊

首先import multiprocessing 和定義job()

import multiprocessing as mp

def job(x):
    return x*x
2、進(jìn)程池Pool()和map()

然后我們定義一個(gè)Pool

pool = mp.Pool()

有了池子之后,就可以讓池子對(duì)應(yīng)某一個(gè)函數(shù),我們向池子里丟數(shù)據(jù),池子就會(huì)返回函數(shù)返回的值。 Pool和之前的Process的不同點(diǎn)是丟向Pool的函數(shù)有返回值,而Process沒(méi)有返回值。

接下來(lái)用map()獲取結(jié)果,在map()中需要放入函數(shù)和需要迭代運(yùn)算的值,然后它會(huì)自動(dòng)分配給CPU核,返回結(jié)果

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

讓我們來(lái)運(yùn)行一下

def multicore():
    pool = mp.Pool()
    res = pool.map(job, range(10))
    print(res)
    
if __name__ == "__main__":
    multicore()

完成代碼:

# -*- coding:utf-8 -*-

"""
@author: Corwien
@file: process_queue.py
@time: 18/8/26 01:12
"""

import multiprocessing as mp

def job(x):
    return x*x  # 注意這里的函數(shù)有return返回值

def multicore():
    pool = mp.Pool()
    res = pool.map(job, range(10))
    print(res)
    
if __name__ == "__main__":
    multicore()

執(zhí)行結(jié)果:

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

我們?cè)趺粗?b>Pool是否真的調(diào)用了多個(gè)核呢?我們可以把迭代次數(shù)增大些,然后打開(kāi)CPU負(fù)載看下CPU運(yùn)行情況

打開(kāi)CPU負(fù)載(Mac):活動(dòng)監(jiān)視器 > CPU > CPU負(fù)載(單擊一下即可)

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

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

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

apply_async()只能傳遞一個(gè)值,它只會(huì)放入一個(gè)核進(jìn)行運(yùn)算,但是傳入值時(shí)要注意是可迭代的,所以在傳入值后需要加逗號(hào), 同時(shí)需要用get()方法獲取返回值

def multicore():
    pool = mp.Pool() 
    res = pool.map(job, range(10))
    print(res)
    res = pool.apply_async(job, (2,))
    # 用get獲得結(jié)果
    print(res.get())

運(yùn)行結(jié)果;

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

Pool默認(rèn)調(diào)用是CPU的核數(shù),傳入processes參數(shù)可自定義CPU核數(shù)

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

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

五、共享內(nèi)存shared memory

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

Shared Value

我們可以通過(guò)使用Value數(shù)據(jù)存儲(chǔ)在一個(gè)共享的內(nèi)存表中。

import multiprocessing as mp

value1 = mp.Value("i", 0) 
value2 = mp.Value("d", 3.14)

其中di參數(shù)用來(lái)設(shè)置數(shù)據(jù)類型的,d表示一個(gè)雙精浮點(diǎn)類型 double,i表示一個(gè)帶符號(hào)的整型。

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 中,有還有一個(gè)Array類,可以和共享內(nèi)存交互,來(lái)實(shí)現(xiàn)在進(jìn)程之間共享數(shù)據(jù)

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

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

錯(cuò)誤形式

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

"""
TypeError: an integer is required
"""
六、進(jìn)程鎖Lock 不加進(jìn)程鎖

讓我們看看沒(méi)有加進(jìn)程鎖時(shí)會(huì)產(chǎn)生什么樣的結(jié)果。

# -*- coding:utf-8 -*-

"""
@author: Corwien
@file: process_no_lock.py
@time: 18/8/26 09:22
"""

import multiprocessing as mp
import time

def job(v, num):
    for _ in range(5):
        time.sleep(0.5) # 暫停0.5秒,讓輸出效果更明顯
        v.value += num  # v.value獲取共享變量值
        print(v.value)

def multicore():
    v = mp.Value("i", 0)  # 定義共享變量
    p1 = mp.Process(target=job, args=(v, 1))
    p2 = mp.Process(target=job, args=(v, 4)) # 設(shè)定不同的number看如何搶奪內(nèi)存
    p1.start()
    p2.start()
    p1.join()
    p2.join()

if __name__ == "__main__":
    multicore()

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

結(jié)果打?。?/p>

?  baseLearn python ./process/process_no_lock.py
1
5
9
9
13
13
17
17
18
18
?  baseLearn

我們可以看到,進(jìn)程1和進(jìn)程2在相互著使用共享內(nèi)存v。

加進(jìn)程鎖

為了解決上述不同進(jìn)程搶共享資源的問(wèn)題,我們可以用加進(jìn)程鎖來(lái)解決。

首先需要定義一個(gè)進(jìn)程鎖

 l = mp.Lock() # 定義一個(gè)進(jìn)程鎖

然后將進(jìn)程鎖的信息傳入各個(gè)進(jìn)程中

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

job()中設(shè)置進(jìn)程鎖的使用,保證運(yùn)行時(shí)一個(gè)進(jìn)程的對(duì)鎖內(nèi)內(nèi)容的獨(dú)占

def job(v, num, l):
    l.acquire() # 鎖住
    for _ in range(5):
        time.sleep(0.1) 
        v.value += num # v.value獲取共享內(nèi)存
        print(v.value)
    l.release() # 釋放

全部代碼:

# -*- coding:utf-8 -*-

"""
@author: Corwien
@file: process_lock.py
@time: 18/8/26 09:22
"""

import multiprocessing as mp
import time

def job(v, num, l):
    l.acquire() # 鎖住
    for _ in range(5):
        time.sleep(0.5) # 暫停0.5秒,讓輸出效果更明顯
        v.value += num  # v.value獲取共享變量值
        print(v.value)
    l.release() # 釋放

def multicore():
    l = mp.Lock() # 定義一個(gè)進(jìn)程鎖
    v = mp.Value("i", 0)  # 定義共享變量
    p1 = mp.Process(target=job, args=(v, 1, l)) # 需要將lock傳入
    p2 = mp.Process(target=job, args=(v, 4, l)) # 設(shè)定不同的number看如何搶奪內(nèi)存
    p1.start()
    p2.start()
    p1.join()
    p2.join()

if __name__ == "__main__":
    multicore()

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

結(jié)果打?。?/p>

?  baseLearn python ./process/process_lock.py
1
2
3
4
5
9
13
17
21
25

顯然,進(jìn)程鎖保證了進(jìn)程p1的完整運(yùn)行,然后才進(jìn)行了進(jìn)程p2的運(yùn)行

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/42314.html

相關(guān)文章

  • python綜合學(xué)習(xí)之多線程

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

    cjie 評(píng)論0 收藏0
  • 零基礎(chǔ)如何學(xué)爬蟲(chóng)技術(shù)

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

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

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

    sydMobile 評(píng)論0 收藏0
  • Python爬蟲(chóng)學(xué)習(xí)路線

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

    liaoyg8023 評(píng)論0 收藏0
  • Python爬蟲(chóng)利器二之Beautiful Soup的用法

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

    cjie 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

gityuan

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<