亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解python之多進程和進程池(Processing庫)

 更新時間:2017年06月09日 10:24:37   作者:今天芒種  
本篇文章主要介紹了詳解python之多進程和進程池(Processing庫),非常具有實用價值,需要的朋友可以參考下

環(huán)境:win7+python2.7

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

首先說下什么是進程:進程是程序在計算機上的一次執(zhí)行活動,當運行一個程序的時候,就啟動了一個進程.而進程又分為系統(tǒng)進程和用戶進程.只要是用于完成操作系統(tǒng)的各種功能的進程就是系統(tǒng)進程,它們就是處于運行狀態(tài)下的操作系統(tǒng)本身;而所有由你啟動的進程都是用戶進程。進程是操作系統(tǒng)進行資源分配的單位。

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

一.多進程的簡單使用

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

進程創(chuàng)建:Process(target=主要運行的函數(shù),name=自定義進程名稱可不寫,args=(參數(shù)))

方法:

  1. is_alive():判斷進程是否存活
  2. join([timeout]):子進程結(jié)束再執(zhí)行下一步,timeout為超時時間,有時進程遇到阻塞,為了程序能夠運行下去而設置超時時間
  3. run():如果在創(chuàng)建Process對象的時候不指定target,那么就會默認執(zhí)行Process的run方法
  4. start():啟動進程,區(qū)分run()
  5. terminate():終止進程,關于終止進程沒有這么簡單,貌似用psutil包會更好,有機會以后了解更多再寫下。

其中,Process以start()啟動某個進程。

屬性:

  1. authkey: 在文檔中authkey()函數(shù)找到這么一句話:Set authorization key of process設置過程的授權密鑰 ,目前沒找到相關應用實例,這個密鑰是怎么用的呢?文章不提
  2. daemon:父進程終止后自動終止,且自己不能產(chǎn)生新進程,必須在start()之前設置
  3. exitcode:進程在運行時為None、如果為–N,表示被信號N結(jié)束
  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函數(shù)的參數(shù),這里要用tulpe類型,如果兩個參數(shù)或更多就是arg=(參數(shù)1,參數(shù)2...),之后用start()啟動進程,我們設置等待p1和p2進程結(jié)束再執(zhí)行下一步.來看下面的運行結(jié)果,fun2和fun1基本在同一時間開始運行,當運行完畢(fun1睡眠4秒,同時fun2睡眠6秒),才執(zhí)行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()處于不同位置會發(fā)生什么

# -*- 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

結(jié)果:

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

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

# -*- 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

結(jié)果:

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運行完接著執(zhí)行下一步),接著繼續(xù)運行主進程的print 'finish',最后fun2運行完畢才結(jié)束

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

結(jié)果:

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進程已經(jīng)結(jié)束(返回False),p2進程仍然在運行(返回True),但p2沒有用join(),所以直接接著執(zhí)行主進程,由于用了daemon=Ture,父進程終止后自動終止,p2進程沒有結(jié)束就強行結(jié)束整個程序了.

3.run()

run()在Process沒有指定target函數(shù)時,默認用run()函數(shù)運行程序,

# -*- 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()
 p=Process()
 p.start()
 p.join()
 b = time.time()
 print 'finish', b - a

結(jié)果:

finish 0.0840001106262

從結(jié)果看出,進程p什么也沒做,為了讓進程正常運行,我們醬紫寫:

目標函數(shù)沒有參數(shù):

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

def fun1():
 print 'this is fun1',time.ctime()
 time.sleep(2)
 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()
 p=Process()
 p.run=fun1
 p.start()
 p.join()
 b = time.time()
 print 'finish', b - a

結(jié)果:

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

目標函數(shù)有參數(shù):

# -*- 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()
 p=Process()
 p.run=fun1(2)
 p.start()
 p.join()
 b = time.time()
 print 'finish', b - a

結(jié)果:

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: 'NoneType' object is not callable
finish 2.0529999733

Process finished with exit code 0

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

二.進程池

對于需要使用幾個甚至十幾個進程時,我們使用Process還是比較方便的,但是如果要成百上千個進程,用Process顯然太笨了,multiprocessing提供了Pool類,即現(xiàn)在要講的進程池,能夠?qū)⒈姸噙M程放在一起,設置一個運行進程上限,每次只運行設置的進程數(shù),等有進程結(jié)束,再添加新的進程

Pool(processes =num):設置運行進程數(shù),當一個進程運行完,會添加新的進程進去

apply_async(函數(shù),(參數(shù))):非阻塞,其中參數(shù)是tulpe類型,

apply(函數(shù),(參數(shù))):阻塞

close():關閉pool,不能再添加新的任務

terminate():結(jié)束運行的進程,不再處理未完成的任務

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

1.單個進程池

# -*- coding:utf-8 -*-
from multiprocessing import Pool
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()
 pool = Pool(processes =3) # 可以同時跑3個進程
 for i in range(3,8):
  pool.apply_async(fun1,(i,))
 pool.close()
 pool.join()
 b=time.time()
 print 'finish',b-a

結(jié)果:

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

從上面的結(jié)果可以看到,設置了3個運行進程上限,15:15:38這個時間同時開始三個進程,當?shù)谝粋€進程結(jié)束時(參數(shù)為3秒那個進程),會添加新的進程,如此循環(huán),直至進程池運行完再執(zhí)行主進程語句b=time.time() print 'finish',b-a .這里用到非阻塞apply_async(),再來對比下阻塞apply()

# -*- coding:utf-8 -*-
from multiprocessing import Pool
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()
 pool = Pool(processes =3) # 可以同時跑3個進程
 for i in range(3,8):
  pool.apply(fun1,(i,))
 pool.close()
 pool.join()
 b=time.time()
 print 'finish',b-a

結(jié)果:

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

可以看到,阻塞是當一個進程結(jié)束后,再進行下一個進程,一般我們都用非阻塞apply_async()

2.多個進程池

上面是使用單個進程池的,對于多個進程池,我們可以用for循環(huán),直接看代碼

# -*- coding:utf-8 -*-
from multiprocessing import Pool
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()
 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 'finish',b-a

結(jié)果:

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.

另外對于沒有參數(shù)的情況,就直接 pool.apply_async(funtion),無需寫上參數(shù).

在學習編寫程序過程,曾遇到不用if _name_ == '_main_':而直接運行程序,這樣結(jié)果會出錯,經(jīng)查詢,在Windows上要想使用進程模塊,就必須把有關進程的代碼寫在當前.py文件的if _name_ == ‘_main_' :語句的下面,才能正常使用Windows下的進程模塊。Unix/Linux下則不需要。原因有人這么說:在執(zhí)行的時候,由于你寫的 py 會被當成module 讀進執(zhí)行。所以,一定要判斷自身是否為 _main_。也就是要:

if __name__ == ‘__main__' :
# do something.

這里我自己還搞不清楚,期待以后能夠理解

學習的過程中,還涉及了經(jīng)常和進程一起運用的隊列Queue和線程threading,有時間以后再寫吧,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 深入理解Python爬蟲代理池服務

    深入理解Python爬蟲代理池服務

    這篇文章主要介紹了Python爬蟲代理池服務的相關知識,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2018-02-02
  • python3 使用函數(shù)求兩個數(shù)的和與差

    python3 使用函數(shù)求兩個數(shù)的和與差

    這篇文章主要介紹了python3 使用函數(shù)求兩個數(shù)的和與差,具有很好的參考價值,希望對大家有所幫助。
    2021-05-05
  • 關于python3中setup.py小概念解析

    關于python3中setup.py小概念解析

    這篇文章主要介紹了關于python3中setup.py小概念解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • Python循環(huán)控制詳解

    Python循環(huán)控制詳解

    本文介紹了Python編程語言中關于for循環(huán)和if條件控制的一些基本使用,包含了單層循環(huán)的退出機制和多層循環(huán)的退出機制,使得我們在滿足特定條件時,可以直接結(jié)束多層循環(huán),需要的朋友可以參考下
    2024-07-07
  • python生成多個只含0,1元素的隨機數(shù)組或列表的實例

    python生成多個只含0,1元素的隨機數(shù)組或列表的實例

    今天小編就為大家分享一篇python生成多個只含0,1元素的隨機數(shù)組或列表的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • pytorch中如何使用DataLoader對數(shù)據(jù)集進行批處理的方法

    pytorch中如何使用DataLoader對數(shù)據(jù)集進行批處理的方法

    這篇文章主要介紹了pytorch中如何使用DataLoader對數(shù)據(jù)集進行批處理的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • Python實現(xiàn)將字典(列表按列)存入csv文件

    Python實現(xiàn)將字典(列表按列)存入csv文件

    這篇文章主要介紹了Python實現(xiàn)將字典(列表按列)存入csv文件方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Python的UTC時間轉(zhuǎn)換講解

    Python的UTC時間轉(zhuǎn)換講解

    今天小編就為大家分享一篇關于Python的UTC時間轉(zhuǎn)換講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • Python實現(xiàn)特定場景去除高光算法詳解

    Python實現(xiàn)特定場景去除高光算法詳解

    這篇文章主要介紹了如何利用Python+OpenCV實現(xiàn)特定場景去除高光算法,文中的示例代碼講解詳細,對我們學習Python有一定的幫助,需要的可以參考一下
    2021-12-12
  • 詳談Python 窗體(tkinter)表格數(shù)據(jù)(Treeview)

    詳談Python 窗體(tkinter)表格數(shù)據(jù)(Treeview)

    今天小編就為大家分享一篇詳談Python 窗體(tkinter)表格數(shù)據(jù)(Treeview),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10

最新評論