真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

python中多進(jìn)程與多線程的用法及場景分析

python中多進(jìn)程與多線程的用法及場景分析,很多新手對此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

創(chuàng)新互聯(lián)從2013年成立,先為黃石等服務(wù)建站,黃石等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為黃石企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

【寫在前面】

        剛開始學(xué)習(xí)Python 并發(fā)查詢或者并發(fā)讀寫時(shí),看到大神們說,多線程是python的雞肋,要學(xué)就學(xué)多進(jìn)程。好吧,我連多線程怎么寫都不知道呢。

        因此,就寫了以下的示例代碼。代碼目的是將test.txt文件中的內(nèi)容,以并發(fā)的方式(多線程/多進(jìn)程)進(jìn)行寫入新文件中,以此來驗(yàn)證兩種并發(fā)方式的效率。

【示例代碼】

# coding=utf-8# @Auther : "鵬哥賊優(yōu)秀"# @Date : 2019/8/10# @Software : PyCharm 
from multiprocessing import Poolimport timeimport threading
# 多進(jìn)程的寫數(shù)據(jù)方法def writedata(content):    with open("new1.txt", "a") as f:        f.writelines(content)        # 定義自己的多線程繼承類class myThread(threading.Thread):    # 聲明myThread是多線程的繼承類    def __init__(self, content):        threading.Thread.__init__(self)        self.content = content        # 多線程運(yùn)行的內(nèi)容    def run(self):        threadingLock = threading.Lock()        threadingLock.acquire()        self.my_writedata(self.content)        threadingLock.release()            # 多線程的寫數(shù)據(jù)方法    def my_writedata(self, content):        with open("new2.txt", "a") as f:            f.writelines(content)
if __name__ == "__main__":    # 創(chuàng)建一個(gè)test.txt,用于數(shù)據(jù)讀取后的寫入    with open("test.txt","w")as f_w:        for i in range(1000):            f_w.write(str(i)+"\n")    # 多進(jìn)程讀寫    print("開始計(jì)時(shí)(多進(jìn)程寫入)")    t0 = time.time()    with open("test.txt", "r", encoding="utf-8")as f:        content = f.readlines()    pool = Pool(processes=4)    pool.map_async(writedata(content), range(len(content)))    pool.close()    pool.join()    t1 = time.time()    print("完成時(shí)間為:{0}".format(t1 - t0))    # 多線程讀寫    print("開始計(jì)時(shí)(多線程寫入)")    t2 = time.time()    with open("test.txt", "r", encoding="utf-8")as f:        content = f.readlines()    threads = []    threadnum = 4    eline = len(content) // threadnum    for i in range(threadnum):        threadtemp = myThread(content[i * eline:(i + 1) * eline])        threadtemp.start()        threads.append(threadtemp)    for i in threads:        i.join()    t3 = time.time()    print("完成時(shí)間為:{0}".format(t3 - t2))

【效果】

python中多進(jìn)程與多線程的用法及場景分析

(第一個(gè)是多進(jìn)程,我開始的時(shí)候打錯(cuò)字了。)

【知識點(diǎn)】

1、多進(jìn)程 代碼流程:

(1)創(chuàng)建進(jìn)程池,并明確進(jìn)程數(shù)。這里我用的是4個(gè)進(jìn)程,是因?yàn)槲冶镜豍C機(jī)的CPU核是4個(gè)。查詢方法:

multiprocessing.cpu_count() 即可知道核數(shù)了

(2)將具體要執(zhí)行的方法加入到進(jìn)程池的異常(map_async)處理中。當(dāng)然也可以用map方法。其中,map_async方法里需要 2個(gè)參數(shù),一個(gè)是具體要執(zhí)行的函數(shù),一個(gè)是表示循環(huán)執(zhí)行的次數(shù),類型是個(gè)list。示例代碼中,因?yàn)槊看蝫irtedata是只寫了content的一行,因此一共要寫len(content)次

(3)最后就是進(jìn)程池后的關(guān)閉,并且在子進(jìn)程關(guān)閉后,主程序才繼續(xù)往下執(zhí)行。join()方法無論 是對多線程不是多進(jìn)程,用途是一樣的。

從代碼實(shí)現(xiàn)上,個(gè)人覺得多進(jìn)程流程簡單明了,并且各進(jìn)程之間寫數(shù)據(jù)是順序的,不會像多線程因?yàn)镚IL的隨機(jī)問題導(dǎo)致進(jìn)程順序混亂的問題。但是唯一的問題是,寫時(shí)間是有點(diǎn)長。

2、多線程代碼流程:

       本文采用的是繼承threading類的方法,即需要重構(gòu)run方法。個(gè)人覺得這種方式,層次更加清晰,而且能根據(jù)自己的目的靈活重構(gòu)run方法。下面重點(diǎn)介紹這種方法。

(1)定義一個(gè)繼承threading類的對象,然后重構(gòu)run方法。其中run方法,需要考慮到鎖的問題。為什么要考慮鎖呢?因?yàn)榇嬖诙鄠€(gè)線程同時(shí)寫文件的情況,如果不加鎖,就會出現(xiàn)多個(gè)線程同時(shí)寫相同一條數(shù)據(jù)的情況,導(dǎo)致出現(xiàn)臟數(shù)據(jù)。

run方法的重構(gòu)也很簡單,先加鎖,再加入自己想要的函數(shù),最后解鎖。

(2)mythread類的編寫,我還是很快就學(xué)會了,但問題是如何將test.txt讓多線程寫入。

一開始,我是這么寫的:

for i in range(threadnum):

    threadtemp = myThread(content)

    threadtemp.start()

    threads.append(threadtemp)

發(fā)現(xiàn)每個(gè)線程都重復(fù)將test.txt里的內(nèi)容都寫了一次,也是相當(dāng)于重復(fù)寫了4次。這里就是和多進(jìn)程用法不同的地方了。

【說明】:

多進(jìn)程,由于不共享資源,因此每個(gè)進(jìn)程都能讀取到不同的content內(nèi)容;多線程,線程之間相互共享,如果要它實(shí)現(xiàn)并發(fā)的功能,必須給每個(gè)線程指定要寫的內(nèi)容。因此最后示例代碼中我就通過 content[i * eline:(i + 1) * eline]給每個(gè)線程指定了不同的寫入內(nèi)容。

(3)在主函數(shù)中,需要把各線程進(jìn)行start,最后就是等各子線程結(jié)束后,主線程再往下執(zhí)行。

從最后代碼行上來看,個(gè)人覺得多線程其實(shí)是麻煩點(diǎn)的。另外,還有個(gè)麻煩的地方是:多線程在調(diào)用時(shí)是隨機(jī)調(diào)用的,什么意思?就是thread1結(jié)束后,第二個(gè)運(yùn)行的是thread9,而不是thread2。那么問題來了,既然大神建議我們用多進(jìn)程,而且多進(jìn)程寫起來簡單,那是不是所有場景都使用多進(jìn)程呢?

3、多線程和多進(jìn)程的使用場景:

多線程使用場景:IO操作密集的場景,比如爬蟲,web訪問等,需要頻繁從網(wǎng)絡(luò)、硬盤、內(nèi)存等讀寫數(shù)據(jù)。這種情況 下,因?yàn)閱尉€程下的IO操作會有IO等待,造成不必要的時(shí)間浪費(fèi),因此采用多線程就能在線程A等待時(shí),開啟線程B的操作。

多進(jìn)程使用場景:CPU計(jì)算密集的場景,比如科學(xué)計(jì)算、循環(huán)處理等。這些場景因?yàn)橛?jì)算工作量大,可能會出現(xiàn)單線程超時(shí)釋放GIL,從而 引發(fā)其他多個(gè)線程的搶奪,反而效果不好。

那為什么大神們說最好用多進(jìn)程呢?應(yīng)該是為了充分利用多核CPU,不然我們的PC機(jī)都要買多核CPU呢?

再回到本示例代碼,從結(jié)果上來看,是多線程的效率更快些,也說明硬盤讀寫的場景更建議用多線程;但是多線程的結(jié)果,即new2.txt里是亂序的,哎。不過我覺得應(yīng)該有辦法解決的,但本人下次再學(xué)習(xí)。

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。


文章名稱:python中多進(jìn)程與多線程的用法及場景分析
文章分享:http://weahome.cn/article/psedgj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部