Python多進程Pool與Process區別,以及用Process實現Pool--part1

  • Python多進程Pool與Process主要區別

(1)Process需要自己管理進程,起一個Process就是起一個新進程;
(2)Pool是進程池,它可以開啓固定數量的進程,然後將任務放到一個池子裏,系統來調度多進程執行池子裏的任務;
Python中多進程主要是通過multiprocessing實現的,通過私有函數all查看,需帶雙下劃線;
import multiprocessing
multiprocessing.all
[‘Array’, ‘AuthenticationError’, ‘Barrier’, ‘BoundedSemaphore’, ‘BufferTooShort’, ‘Condition’, ‘Event’, ‘JoinableQueue’, ‘Lock’, ‘Manager’, ‘Pipe’, ‘Pool’, ‘Process’, ‘ProcessError’, ‘Queue’, ‘RLock’, ‘RawArray’, ‘RawValue’, ‘Semaphore’, ‘SimpleQueue’, ‘TimeoutError’, ‘Value’, ‘active_children’, ‘allow_connection_pickling’, ‘cpu_count’, ‘current_process’, ‘freeze_support’, ‘get_all_start_methods’, ‘get_context’, ‘get_logger’, ‘get_start_method’, ‘log_to_stderr’, ‘set_executable’, ‘set_forkserver_preload’, ‘set_start_method’]

再看庫裏面Process函數的定義:

class Process(object):
    def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
        self.name = ''
        self.daemon = False
        self.authkey = None
        self.exitcode = None
        self.ident = 0
        self.pid = 0
        self.sentinel = None
    def run(self):
        pass
    def start(self):
        pass
    def terminate(self):
        pass
    def join(self, timeout=None):
        pass	
    def is_alive(self):
        return False

進程創建:Process(target=主要運行的函數,name=自定義進程名稱可不寫,args=(參數))
方法:is_alive():判斷進程是否存活
join([timeout]):子進程結束再執行下一步,timeout爲超時時間,有時進程遇到阻塞,爲了程序能夠運行下去而設置超時時間
run():如果在創建Process對象的時候不指定target,那麼就會默認執行Process的run方法
start():啓動進程,區分run()
terminate():終止進程,關於終止進程沒有這麼簡單,貌似用psutil包會更好,有機會以後瞭解更多再寫下。
其中,Process以start()啓動某個進程。
屬性:authkey: 在文檔中authkey()函數找到這麼一句話:Set authorization key of process設置過程的授權密鑰 ,目前沒找到相關應用實例,這個密鑰是怎麼用的呢?文章不提
daemon:父進程終止後自動終止,且自己不能產生新進程,必須在start()之前設置
exitcode:進程在運行時爲None、如果爲–N,表示被信號N結束
name:進程的名字,自定義
pid:每個進程有唯一的PID編號。
參考:https://www.jianshu.com/p/a7a2ee7c5463

import multiprocessing
from multiprocessing import Process
#
# multiprocessing.__all__
# ['Array', 'AuthenticationError', 'Barrier', 'BoundedSemaphore', 'BufferTooShort', 'Condition', 'Event', 'JoinableQueue', 'Lock', 'Manager', 'Pipe', 'Pool', 'Process', 'ProcessError', 'Queue', 'RLock', 'RawArray', 'RawValue', 'Semaphore', 'SimpleQueue', 'TimeoutError', 'Value', 'active_children', 'allow_connection_pickling', 'cpu_count', 'current_process', 'freeze_support', 'get_all_start_methods', 'get_context', 'get_logger', 'get_start_method', 'log_to_stderr', 'set_executable', 'set_forkserver_preload', 'set_start_method']
# a = Process()
# -*- coding:utf-8 -*-

################start(),join()#########################
from multiprocessing import Process
import time
from multiprocessing.pool import Pool


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())


############demo 1##################
# 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)
'''
只有func2:
this is fun2 Sun Jan  6 17:02:25 2019
fun2 finish Sun Jan  6 17:02:31 2019
finish 6.02819037437439'''


'''
func1和func2都有:
this is fun1 Sun Jan  6 17:03:09 2019
this is fun2 Sun Jan  6 17:03:09 2019
fun1 finish Sun Jan  6 17:03:13 2019
fun2 finish Sun Jan  6 17:03:15 2019
finish 6.0113677978515625

證明當start和join位置爲:
p1.start()
p2.start()
p1.join()
p2.join()
的時候,func1和func2是同時運行的,主進程最後運行!!!!!

'''

##############demo 2 ################
# 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 Sun Jan  6 17:21:24 2019
fun1 finish Sun Jan  6 17:21:28 2019
this is fun2 Sun Jan  6 17:21:28 2019
fun2 finish Sun Jan  6 17:21:34 2019
finish 10.016567707061768

證明當start和join位置爲:
p1.start()
p1.join()
p2.start()
p2.join()
的時候,func1和func2不是同時運行的!!!!!

'''


############demo 3##############
# 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 Sun Jan  6 17:46:36 2019
this is fun2 Sun Jan  6 17:46:36 2019
fun1 finish Sun Jan  6 17:46:40 2019
finish 4.007489204406738
fun2 finish Sun Jan  6 17:46:42 2019
結果:
這次是運行完fun1(因爲p1進程有用join(),
所以主程序等待p1運行完接着執行下一步),
接着繼續運行主進程的print 'finish',最後fun2運行完畢才結束;

fun2開啓之後會等待主進程結束之後再運行;
'''



################daemon,alive屬性##########################
# 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 fun1 Sun Jan  6 17:52:08 2019
this is fun2 Sun Jan  6 17:52:08 2019
fun1 finish Sun Jan  6 17:52:12 2019
<Process(fun1進程, stopped daemon)> <Process(fun2進程, started daemon)>
進程1: False 進程2: True
finish 4.006983280181885

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


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


'''


#Pool進程池使用-----------單進程---------##
#####################Pool---pool.apply_async---非阻塞---###############################
# 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)

'''this is fun1 Sun Jan  6 17:58:29 2019
this is fun1 Sun Jan  6 17:58:29 2019
this is fun1 Sun Jan  6 17:58:29 2019
fun1 finish Sun Jan  6 17:58:32 2019
this is fun1 Sun Jan  6 17:58:32 2019
fun1 finish Sun Jan  6 17:58:33 2019
this is fun1 Sun Jan  6 17:58:33 2019
fun1 finish Sun Jan  6 17:58:34 2019
fun1 finish Sun Jan  6 17:58:38 2019
fun1 finish Sun Jan  6 17:58:40 2019
finish 11.06075119972229  


從上面的結果可以看到,設置了3個運行進程上限,6 17:58:29這個時間同時開始三個進程,
當第一個進程結束時(參數爲3秒那個進程),會添加新的進程,如此循環,
直至進程池運行完再執行主進程語句b=time.time() 
print 'finish',b-a .這裏用到非阻塞apply_async(),再來對比下阻塞apply()

'''

#####################Pool---pool.apply--阻塞---###############################
# 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)

'''
this is fun1 Sun Jan  6 18:05:10 2019
fun1 finish Sun Jan  6 18:05:13 2019
this is fun1 Sun Jan  6 18:05:13 2019
fun1 finish Sun Jan  6 18:05:17 2019
this is fun1 Sun Jan  6 18:05:17 2019
fun1 finish Sun Jan  6 18:05:22 2019
this is fun1 Sun Jan  6 18:05:22 2019
fun1 finish Sun Jan  6 18:05:28 2019
this is fun1 Sun Jan  6 18:05:28 2019
fun1 finish Sun Jan  6 18:05:36 2019
finish 25.07084083557129

可以看到,阻塞是當一個進程結束後,再進行下一個進程,一般我們都用非阻塞apply_async()
'''
#Pool進程池使用-----------多個進程池--for循環實現---------##
#下面程序相當於開了兩個進程池,分別實現兩個不同的功能,每個進程池含3個進程;
####################################################
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)
'''
this is fun1 Sun Jan  6 18:13:20 2019
this is fun1 Sun Jan  6 18:13:20 2019
this is fun1 Sun Jan  6 18:13:20 2019
fun1 finish Sun Jan  6 18:13:23 2019
this is fun1 Sun Jan  6 18:13:23 2019
fun1 finish Sun Jan  6 18:13:24 2019
this is fun1 Sun Jan  6 18:13:24 2019
fun1 finish Sun Jan  6 18:13:25 2019
this is fun2 Sun Jan  6 18:13:25 2019
fun2 finish Sun Jan  6 18:13:28 2019
this is fun2 Sun Jan  6 18:13:28 2019
fun1 finish Sun Jan  6 18:13:29 2019
this is fun2 Sun Jan  6 18:13:29 2019
fun1 finish Sun Jan  6 18:13:31 2019
this is fun2 Sun Jan  6 18:13:31 2019
fun2 finish Sun Jan  6 18:13:32 2019
this is fun2 Sun Jan  6 18:13:32 2019
fun2 finish Sun Jan  6 18:13:34 2019
fun2 finish Sun Jan  6 18:13:37 2019
fun2 finish Sun Jan  6 18:13:39 2019
finish 19.056739807128906

結果:
在fun1運行完接着運行fun2.
另外對於沒有參數的情況,就直接 pool.apply_async(funtion),無需寫上參數.
'''

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章