搜尋
首頁後端開發Python教學python中多進程和進程池(Processing庫)的實例程式碼

本篇文章主要介紹了詳解python之多進程和進程池(Processing庫),非常具有實用價值,需要的朋友可以參考下

環境:win7+python2.7

一直想學習多進程或多線程,但之前只是單純看一點基礎知識還有簡單的介紹,無法理解怎麼去應用,直到前段時間看了github的一個爬蟲項目涉及到多進程,多執行緒相關內容,一邊看一邊百度相關知識點,現在把一些相關知識點和一些應用寫下來做個記錄.

首先說下什麼是進程:進程是程式在電腦上的一次執行活動,當運行一個程式的時候,就啟動了一個進程.而進程又分為系統進程和用戶進程.只要是用於完成操作系統的各種功能的進程就是系統進程,它們就是處於運行狀態下的作業系統本身;而所有由你啟動的進程都是使用者進程。進程是作業系統進行資源分配的單位。

直觀點說,在任務管理器的用戶名上標明system的是系統進程,標明administrator的是用戶進程,另外net是網洛,lcacal service是本地服務,關於進程更加具體的信息可以百科,這裡得省點力氣,不然收不回了.

一.多進程的簡單使用

如圖,multiprocessing有多個函數,很多我也還沒去了解,這裡只講我目前了解的.

#進程創建:Process(target=主要運行的函數,name=自訂進程名稱可不寫,args=(參數))

方法:

  1. #is_alive():判斷進程是否存活

  2. ##join([timeout]):子進程結束再執行下一步,timeout為超時時間,有時進程遇到阻塞,為了程式能夠運行下去而設定超時時間
  3. run():如果在建立Process物件的時候不指定target,那麼就會預設執行Process的run方法
  4. start():啟動流程,區分run()

  5. terminate():終止進程,關於終止進程沒有這麼簡單,貌似用psutil套件會更好,有機會以後了解更多再寫下。

其中,Process以start()啟動某個行程。
屬性:

  1. authkey: 在文件中authkey()函數找到這麼一句話:Set authorization key of process設定過程的授權金鑰,目前沒找到相關應用實例,這個金鑰是怎麼用的呢?文章不提
  2. #daemon:父行程終止後自動終止,且自己不能產生新進程,必須在start()之前設定
  3. exitcode:進程在執行時為None、如果為–N,表示被訊號N結束
  4. name:進程的名字,自訂
  5. pid:每個行程都有唯一的PID編號。

1.Process(),start(),join()

# -*- coding:utf-8 -*-
from multiprocessing import Process
import time

def fun1(t):
 print 'this is fun1',time.ctime()
 time.sleep(t)
 print 'fun1 finish',time.ctime()

def fun2(t):
 print 'this is fun2',time.ctime()
 time.sleep(t)
 print 'fun2 finish',time.ctime()

if name == 'main':
 a=time.time()
 p1=Process(target=fun1,args=(4,))
 p2 = Process(target=fun2, args=(6,))
 p1.start()
 p2.start()
 p1.join()
 p2.join()
 b=time.time()
 print 'finish',b-a

這裡一共開了兩個行程,p1和p2, arg=(4,)中的4是fun1函數的參數,這裡要用tulpe類型,如果兩個參數或更多就是arg=(參數1,參數2...),之後用start()啟動進程,我們設定等待p1和p2進程結束再執行下一步.來看下面的運行結果,fun2和fun1基本上在同一時間開始運行,當運行完畢(fun1睡眠4秒,同時fun2睡眠6秒),才執行print ' finish',b-a語句

this is fun2 Mon Jun 05 13:48:04 2017
this is fun1 Mon Jun 05 13:48:04 2017
fun1 finish Mon Jun 05 13:48:08 2017
fun2 finish Mon Jun 05 13:48:10 2017
finish 6.20300006866

Process finished with exit code 0

我們再來看下start()與join()處於不同位置會發生什麼

# -*- coding:utf-8 -*-
from multiprocessing import Process
import time

def fun1(t):
 print 'this is fun1',time.ctime()
 time.sleep(t)
 print 'fun1 finish',time.ctime()

def fun2(t):
 print 'this is fun2',time.ctime()
 time.sleep(t)
 print 'fun2 finish',time.ctime()

if name == 'main':
 a=time.time()
 p1=Process(target=fun1,args=(4,))
 p2 = Process(target=fun2, args=(6,))
 p1.start()
 p1.join()
 p2.start()
 p2.join()
 b=time.time()
 print 'finish',b-a

結果:

this is fun1 Mon Jun 05 14:19:28 2017
fun1 finish Mon Jun 05 14:19:32 2017
this is fun2 Mon Jun 05 14:19:32 2017
fun2 finish Mon Jun 05 14:19:38 2017
finish 10.1229999065

Process finished with exit code 0

看,現在是先運行fun1函數,運行完畢再運行fun2接著再是print 'finish',即先運行進程p1再運行進程p2,感受到join()的魅力了吧.現在再試試註釋掉join()看看又會出現什麼

# -*- coding:utf-8 -*-
from multiprocessing import Process
import time

def fun1(t):
 print 'this is fun1',time.ctime()
 time.sleep(t)
 print 'fun1 finish',time.ctime()

def fun2(t):
 print 'this is fun2',time.ctime()
 time.sleep(t)
 print 'fun2 finish',time.ctime()

if name == 'main':
 a=time.time()
 p1=Process(target=fun1,args=(4,))
 p2 = Process(target=fun2, args=(6,))
 p1.start()
 p2.start()
 p1.join()
 #p2.join()
 b=time.time()
 print 'finish',b-a

結果:

this is fun1 Mon Jun 05 14:23:57 2017
this is fun2 Mon Jun 05 14:23:58 2017
fun1 finish Mon Jun 05 14:24:01 2017
finish 4.05900001526
fun2 finish Mon Jun 05 14:24:04 2017

Process finished with exit code 0

這次是運行完fun1(因為p1進程有用join(),所以主程式等待p1運行完接著執行下一步),接著繼續運行主進程的print 'finish',最後fun2運行完畢才結束

2.name,daemon,is_alive():

# -*- coding:utf-8 -*-
from multiprocessing import Process
import time

def fun1(t):
 print 'this is fun1',time.ctime()
 time.sleep(t)
 print 'fun1 finish',time.ctime()

def fun2(t):
 print 'this is fun2',time.ctime()
 time.sleep(t)
 print 'fun2 finish',time.ctime()

if name == 'main':
 a=time.time()
 p1=Process(name='fun1进程',target=fun1,args=(4,))
 p2 = Process(name='fun2进程',target=fun2, args=(6,))
 p1.daemon=True
 p2.daemon = True
 p1.start()
 p2.start()
 p1.join()
 print p1,p2
 print '进程1:',p1.is_alive(),'进程2:',p2.is_alive()
 #p2.join()
 b=time.time()
 print 'finish',b-a

#結果:

this is fun2 Mon Jun 05 14:43:49 2017
this is fun1 Mon Jun 05 14:43:49 2017
fun1 finish Mon Jun 05 14:43:53 2017
<Process(fun1进程, stopped daemon)> <Process(fun2进程, started daemon)>
进程1: False 进程2: True
finish 4.06500005722

Process finished with exit code 0

可以看到,name是給進程賦予名字, 運行到print '進程1:',p1.is_alive(),'進程2:',p2.is_alive() 這句話的時候,p1進程已經結束(返回False),p2進程仍在運行(返回True),但p2沒有用join(),所以直接接著執行主進程,由於用了daemon=Ture,父進程終止後自動終止,p2進程沒有結束就強行結束整個程式了.

3.run()

run()在Process沒有指定target函數時,預設用run()函數執行程式,

# -*- coding:utf-8 -*-
from multiprocessing import Process
import time

def fun1(t):
 print &#39;this is fun1&#39;,time.ctime()
 time.sleep(t)
 print &#39;fun1 finish&#39;,time.ctime()

def fun2(t):
 print &#39;this is fun2&#39;,time.ctime()
 time.sleep(t)
 print &#39;fun2 finish&#39;,time.ctime()

if name == &#39;main&#39;:
 a = time.time()
 p=Process()
 p.start()
 p.join()
 b = time.time()
 print &#39;finish&#39;, b - a

結果:

finish 0.0840001106262

從結果看出,進程p什麼也沒做,為了讓進程正常運作,我們醬紫寫:

目標函數沒有參數:

# -*- coding:utf-8 -*-
from multiprocessing import Process
import time

def fun1():
 print &#39;this is fun1&#39;,time.ctime()
 time.sleep(2)
 print &#39;fun1 finish&#39;,time.ctime()

def fun2(t):
 print &#39;this is fun2&#39;,time.ctime()
 time.sleep(t)
 print &#39;fun2 finish&#39;,time.ctime()

if name == &#39;main&#39;:
 a = time.time()
 p=Process()
 p.run=fun1
 p.start()
 p.join()
 b = time.time()
 print &#39;finish&#39;, b - a

結果:

this is fun1 Mon Jun 05 16:34:41 2017
fun1 finish Mon Jun 05 16:34:43 2017
finish 2.11500000954

Process finished with exit code 0

目標函數有參數:

# -*- coding:utf-8 -*-
from multiprocessing import Process
import time

def fun1(t):
 print &#39;this is fun1&#39;,time.ctime()
 time.sleep(t)
 print &#39;fun1 finish&#39;,time.ctime()

def fun2(t):
 print &#39;this is fun2&#39;,time.ctime()
 time.sleep(t)
 print &#39;fun2 finish&#39;,time.ctime()

if name == &#39;main&#39;:
 a = time.time()
 p=Process()
 p.run=fun1(2)
 p.start()
 p.join()
 b = time.time()
 print &#39;finish&#39;, b - a

結果:

this is fun1 Mon Jun 05 16:36:27 2017
fun1 finish Mon Jun 05 16:36:29 2017
Process Process-1:
Traceback (most recent call last):
 File "E:\Anaconda2\lib\multiprocessing\process.py", line 258, in _bootstrap
 self.run()
TypeError: &#39;NoneType&#39; object is not callable
finish 2.0529999733

Process finished with exit code 0

目標函數有參數的出現了異常,為什麼呢?我現在還找不到原因,但是實踐發現,當最後一個參數賦予進程運行後,沒有其他參數,就會出現這個異常,有人知道的望告知.

二.進程池# #####

对于需要使用几个甚至十几个进程时,我们使用Process还是比较方便的,但是如果要成百上千个进程,用Process显然太笨了,multiprocessing提供了Pool类,即现在要讲的进程池,能够将众多进程放在一起,设置一个运行进程上限,每次只运行设置的进程数,等有进程结束,再添加新的进程

Pool(processes =num):设置运行进程数,当一个进程运行完,会添加新的进程进去

apply_async(函数,(参数)):非阻塞,其中参数是tulpe类型,

apply(函数,(参数)):阻塞

close():关闭pool,不能再添加新的任务

terminate():结束运行的进程,不再处理未完成的任务

join():和Process介绍的作用一样, 但要在close或terminate之后使用。

1.单个进程池

# -*- coding:utf-8 -*-
from multiprocessing import Pool
import time

def fun1(t):
 print &#39;this is fun1&#39;,time.ctime()
 time.sleep(t)
 print &#39;fun1 finish&#39;,time.ctime()

def fun2(t):
 print &#39;this is fun2&#39;,time.ctime()
 time.sleep(t)
 print &#39;fun2 finish&#39;,time.ctime()

if name == &#39;main&#39;:
 a=time.time()
 pool = Pool(processes =3) # 可以同时跑3个进程
 for i in range(3,8):
  pool.apply_async(fun1,(i,))
 pool.close()
 pool.join()
 b=time.time()
 print &#39;finish&#39;,b-a

结果:

this is fun1 Mon Jun 05 15:15:38 2017
this is fun1 Mon Jun 05 15:15:38 2017
this is fun1 Mon Jun 05 15:15:38 2017
fun1 finish Mon Jun 05 15:15:41 2017
this is fun1 Mon Jun 05 15:15:41 2017
fun1 finish Mon Jun 05 15:15:42 2017
this is fun1 Mon Jun 05 15:15:42 2017
fun1 finish Mon Jun 05 15:15:43 2017
fun1 finish Mon Jun 05 15:15:47 2017
fun1 finish Mon Jun 05 15:15:49 2017
finish 11.1370000839

Process finished with exit code 0

从上面的结果可以看到,设置了3个运行进程上限,15:15:38这个时间同时开始三个进程,当第一个进程结束时(参数为3秒那个进程),会添加新的进程,如此循环,直至进程池运行完再执行主进程语句b=time.time() print 'finish',b-a .这里用到非阻塞apply_async(),再来对比下阻塞apply()

# -*- coding:utf-8 -*-
from multiprocessing import Pool
import time

def fun1(t):
 print &#39;this is fun1&#39;,time.ctime()
 time.sleep(t)
 print &#39;fun1 finish&#39;,time.ctime()

def fun2(t):
 print &#39;this is fun2&#39;,time.ctime()
 time.sleep(t)
 print &#39;fun2 finish&#39;,time.ctime()

if name == &#39;main&#39;:
 a=time.time()
 pool = Pool(processes =3) # 可以同时跑3个进程
 for i in range(3,8):
  pool.apply(fun1,(i,))
 pool.close()
 pool.join()
 b=time.time()
 print &#39;finish&#39;,b-a

结果:

this is fun1 Mon Jun 05 15:59:26 2017
fun1 finish Mon Jun 05 15:59:29 2017
this is fun1 Mon Jun 05 15:59:29 2017
fun1 finish Mon Jun 05 15:59:33 2017
this is fun1 Mon Jun 05 15:59:33 2017
fun1 finish Mon Jun 05 15:59:38 2017
this is fun1 Mon Jun 05 15:59:38 2017
fun1 finish Mon Jun 05 15:59:44 2017
this is fun1 Mon Jun 05 15:59:44 2017
fun1 finish Mon Jun 05 15:59:51 2017
finish 25.1610000134

Process finished with exit code 0

可以看到,阻塞是当一个进程结束后,再进行下一个进程,一般我们都用非阻塞apply_async()

2.多个进程池

上面是使用单个进程池的,对于多个进程池,我们可以用for循环,直接看代码

# -*- coding:utf-8 -*-
from multiprocessing import Pool
import time

def fun1(t):
 print &#39;this is fun1&#39;,time.ctime()
 time.sleep(t)
 print &#39;fun1 finish&#39;,time.ctime()

def fun2(t):
 print &#39;this is fun2&#39;,time.ctime()
 time.sleep(t)
 print &#39;fun2 finish&#39;,time.ctime()

if name == &#39;main&#39;:
 a=time.time()
 pool = Pool(processes =3) # 可以同时跑3个进程
 for fun in [fun1,fun2]:
  for i in range(3,8):
   pool.apply_async(fun,(i,))
 pool.close()
 pool.join()
 b=time.time()
 print &#39;finish&#39;,b-a

结果:

this is fun1 Mon Jun 05 16:04:38 2017
this is fun1 Mon Jun 05 16:04:38 2017
this is fun1 Mon Jun 05 16:04:38 2017
fun1 finish Mon Jun 05 16:04:41 2017
this is fun1 Mon Jun 05 16:04:41 2017
fun1 finish Mon Jun 05 16:04:42 2017
this is fun1 Mon Jun 05 16:04:42 2017
fun1 finish Mon Jun 05 16:04:43 2017
this is fun2 Mon Jun 05 16:04:43 2017
fun2 finish Mon Jun 05 16:04:46 2017
this is fun2 Mon Jun 05 16:04:46 2017
fun1 finish Mon Jun 05 16:04:47 2017
this is fun2 Mon Jun 05 16:04:47 2017
fun1 finish Mon Jun 05 16:04:49 2017
this is fun2 Mon Jun 05 16:04:49 2017
fun2 finish Mon Jun 05 16:04:50 2017
this is fun2 Mon Jun 05 16:04:50 2017
fun2 finish Mon Jun 05 16:04:52 2017
fun2 finish Mon Jun 05 16:04:55 2017
fun2 finish Mon Jun 05 16:04:57 2017
finish 19.1670000553

Process finished with exit code 0

看到了,在fun1运行完接着运行fun2.

另外对于没有参数的情况,就直接 pool.apply_async(funtion),无需写上参数.

在学习编写程序过程,曾遇到不用if _name_ == '_main_':而直接运行程序,这样结果会出错,经查询,在Windows上要想使用进程模块,就必须把有关进程的代码写在当前.py文件的if _name_ == ‘_main_' :语句的下面,才能正常使用Windows下的进程模块。Unix/Linux下则不需要。原因有人这么说:在执行的時候,由于你写的 py 会被当成module 读进执行。所以,一定要判断自身是否为 _main_。也就是要:

if name == ‘main&#39; :
# do something.

这里我自己还搞不清楚,期待以后能够理解

以上是python中多進程和進程池(Processing庫)的實例程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python:遊戲,Guis等Python:遊戲,Guis等Apr 13, 2025 am 12:14 AM

Python在遊戲和GUI開發中表現出色。 1)遊戲開發使用Pygame,提供繪圖、音頻等功能,適合創建2D遊戲。 2)GUI開發可選擇Tkinter或PyQt,Tkinter簡單易用,PyQt功能豐富,適合專業開發。

Python vs.C:申請和用例Python vs.C:申請和用例Apr 12, 2025 am 12:01 AM

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。Python以简洁和强大的生态系统著称,C 则以高性能和底层控制能力闻名。

2小時的Python計劃:一種現實的方法2小時的Python計劃:一種現實的方法Apr 11, 2025 am 12:04 AM

2小時內可以學會Python的基本編程概念和技能。 1.學習變量和數據類型,2.掌握控制流(條件語句和循環),3.理解函數的定義和使用,4.通過簡單示例和代碼片段快速上手Python編程。

Python:探索其主要應用程序Python:探索其主要應用程序Apr 10, 2025 am 09:41 AM

Python在web開發、數據科學、機器學習、自動化和腳本編寫等領域有廣泛應用。 1)在web開發中,Django和Flask框架簡化了開發過程。 2)數據科學和機器學習領域,NumPy、Pandas、Scikit-learn和TensorFlow庫提供了強大支持。 3)自動化和腳本編寫方面,Python適用於自動化測試和系統管理等任務。

您可以在2小時內學到多少python?您可以在2小時內學到多少python?Apr 09, 2025 pm 04:33 PM

兩小時內可以學到Python的基礎知識。 1.學習變量和數據類型,2.掌握控制結構如if語句和循環,3.了解函數的定義和使用。這些將幫助你開始編寫簡單的Python程序。

如何在10小時內通過項目和問題驅動的方式教計算機小白編程基礎?如何在10小時內通過項目和問題驅動的方式教計算機小白編程基礎?Apr 02, 2025 am 07:18 AM

如何在10小時內教計算機小白編程基礎?如果你只有10個小時來教計算機小白一些編程知識,你會選擇教些什麼�...

如何在使用 Fiddler Everywhere 進行中間人讀取時避免被瀏覽器檢測到?如何在使用 Fiddler Everywhere 進行中間人讀取時避免被瀏覽器檢測到?Apr 02, 2025 am 07:15 AM

使用FiddlerEverywhere進行中間人讀取時如何避免被檢測到當你使用FiddlerEverywhere...

Python 3.6加載Pickle文件報錯"__builtin__"模塊未找到怎麼辦?Python 3.6加載Pickle文件報錯"__builtin__"模塊未找到怎麼辦?Apr 02, 2025 am 07:12 AM

Python3.6環境下加載Pickle文件報錯:ModuleNotFoundError:Nomodulenamed...

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。