Python成長之路Python并發學習:多進程與多線程的用法及場景介紹

      網友投稿 988 2025-03-31

      剛開始學習Python 并發查詢或者并發讀寫時,看到大神們說,多線程是python的雞肋,要學就學多進程。好吧,我連多線程怎么寫都不知道呢。

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

      示例代碼

      #?coding=utf-8 #?@Auther?:?"鵬哥賊優秀" #?@Date?:?2019/8/10 #?@Software?:?PyCharm? ? from?multiprocessing?import?Pool import?time import?threading ? #?多進程的寫數據方法 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 ???? ????#?多線程運行的內容 ????def?run(self): ????????threadingLock?=?threading.Lock() ????????threadingLock.acquire() ????????self.my_writedata(self.content) ????????threadingLock.release() ???????? ????#?多線程的寫數據方法 ????def?my_writedata(self,?content): ????????with?open("new2.txt",?"a")?as?f: ????????????f.writelines(content) ? if?__name__?==?"__main__": ????#?創建一個test.txt,用于數據讀取后的寫入 ????with?open("test.txt","w")as?f_w: ????????for?i?in?range(1000): ????????????f_w.write(str(i)+"\n") ????#?多進程讀寫 ????print("開始計時(多進程寫入)") ????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("完成時間為:{0}".format(t1?-?t0)) ????#?多線程讀寫 ????print("開始計時(多線程寫入)") ????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("完成時間為:{0}".format(t3?-?t2))

      效果

      (第一個是多進程,我開始的時候打錯字了。)

      知識點

      1、多進程 代碼流程:

      (1)創建進程池,并明確進程數。這里我用的是4個進程,是因為我本地PC機的CPU核是4個。查詢方法:

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

      (2)將具體要執行的方法加入到進程池的異常(map_async)處理中。當然也可以用map方法。其中,map_async方法里需要 2個參數,一個是具體要執行的函數,一個是表示循環執行的次數,類型是個list。示例代碼中,因為每次wirtedata是只寫了content的一行,因此一共要寫len(content)次

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

      從代碼實現上,個人覺得多進程流程簡單明了,并且各進程之間寫數據是順序的,不會像多線程因為GIL的隨機問題導致進程順序混亂的問題。但是唯一的問題是,寫時間是有點長。

      2、多線程代碼流程:

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

      (1)定義一個繼承threading類的對象,然后重構run方法。其中run方法,需要考慮到鎖的問題。為什么要考慮鎖呢?因為存在多個線程同時寫文件的情況,如果不加鎖,就會出現多個線程同時寫相同一條數據的情況,導致出現臟數據。

      run方法的重構也很簡單,先加鎖,再加入自己想要的函數,最后解鎖。

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

      一開始,我是這么寫的:

      for?i?in?range(threadnum): ????threadtemp?=?myThread(content) ????threadtemp.start() ????threads.append(threadtemp)

      發現每個線程都重復將test.txt里的內容都寫了一次,也是相當于重復寫了4次。這里就是和多進程用法不同的地方了。

      說明

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

      (3)在主函數中,需要把各線程進行start,最后就是等各子線程結束后,主線程再往下執行。

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

      3、多線程和多進程的使用場景:

      多線程使用場景:IO操作密集的場景,比如爬蟲,web訪問等,需要頻繁從網絡、硬盤、內存等讀寫數據。這種情況 下,因為單線程下的IO操作會有IO等待,造成不必要的時間浪費,因此采用多線程就能在線程A等待時,開啟線程B的操作。

      多進程使用場景:CPU計算密集的場景,比如科學計算、循環處理等。這些場景因為計算工作量大,可能會出現單線程超時釋放GIL,從而 引發其他多個線程的搶奪,反而效果不好。

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

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

      參考

      http://www.uml.org.cn/python/201901221.asp 如果還不理解,建議先看這篇文章,我也是看了這篇文章后就懂了怎么寫多進程。

      http://www.uml.org.cn/python/201901221.asp

      https://blog.csdn.net/qq610850653/article/details/79455323

      【Python成長之路】python并發學習:多進程與多線程的用法及場景介紹

      python

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:制作財務報表表格(寫財務報表)
      下一篇:excel中如何使sheet1和sheet2關聯?(如何使sheet1與sheet2相關聯)
      相關文章
      亚洲视频在线一区二区| 一区二区亚洲精品精华液| 亚洲精品国产第一综合99久久| 久久亚洲私人国产精品vA| 亚洲国产精品嫩草影院在线观看 | 亚洲国产AV无码一区二区三区| 亚洲一区在线观看视频| 亚洲一区免费在线观看| 亚洲国产电影在线观看| 久久久久亚洲精品日久生情 | 亚洲日本中文字幕天天更新| 亚洲免费二区三区| 亚洲一区二区三区在线| 2020年亚洲天天爽天天噜| 亚洲香蕉久久一区二区三区四区| 久久精品亚洲AV久久久无码| 久久精品国产99国产精品亚洲| 亚洲国产最大av| 亚洲熟女乱色一区二区三区| 亚洲欧美日韩中文字幕一区二区三区 | 国产午夜亚洲不卡| 国产成人高清亚洲| 亚洲精品偷拍视频免费观看 | 国产综合成人亚洲区| 亚洲av无码不卡私人影院| 亚洲美女在线国产| 久久精品国产精品亚洲人人| 在线亚洲97se亚洲综合在线| 国产亚洲精品自在久久| 久久久久亚洲Av片无码v| 亚洲国产精品久久久久婷婷老年 | 国产亚洲蜜芽精品久久| 亚洲欧洲日产国码高潮αv| 在线精品亚洲一区二区三区| 国产精品亚洲A∨天堂不卡| 亚洲精选在线观看| 亚洲依依成人精品| 亚洲经典千人经典日产| xvideos亚洲永久网址| 亚洲真人无码永久在线| 亚洲色图在线观看|