Python中的多進程

1、python併發編程之多進程

一、multiprocessing模塊介紹(

from multiprocessing import Process

二、Process類的介紹

 1 建立進程的類:python

Process([group [, target [, name [, args [, kwargs]]]]]),由該類實例化獲得的對象,表示一個子進程中的任務(還沒有啓動)

強調:
1. 須要使用關鍵字的方式來指定參數 2. args指定的爲傳給target函數的位置參數,是一個元組形式,必須有逗號

 



 

2參數介紹:編程

1 group參數未使用,值始終爲None
2 
3 target表示調用對象,即子進程要執行的任務
4 
5 args表示調用對象的位置參數元組,args=(1,2,'egon',)
6 
7 kwargs表示調用對象的字典,kwargs={'name':'egon','age':18}
8 
9 name爲子進程的名稱

3方法介紹:windows

 1 p.start():啓動進程,並調用該子進程中的p.run() 
 2 p.run():進程啓動時運行的方法,正是它去調用target指定的函數,咱們自定義類的類中必定要實現該方法  
 3 
 4 p.terminate():強制終止進程p,不會進行任何清理操做,若是p建立了子進程,該子進程就成了殭屍進程,使用該方法須要特別當心這種狀況。若是p還保存了一個鎖那麼也將不會被釋放,進而致使死鎖
 5 p.is_alive():若是p仍然運行,返回True
 6 
 7 p.join([timeout]):主線程等待p終止(強調:是主線程處於等的狀態,而p是處於運行的狀態)。timeout是可選的超時時間,須要強調的是,p.join只能join住start開啓的進程,而不能join住run開啓的進程  

4屬性介紹:安全

1 p.daemon:默認值爲False,若是設爲True,表明p爲後臺運行的守護進程,當p的父進程終止時,p也隨之終止,而且設定爲True後,p不能建立本身的新進程,必須在p.start()以前設置
2 
3 p.name:進程的名稱
4 
5 p.pid:進程的pid
6 
7 p.exitcode:進程在運行時爲None、若是爲–N,表示被信號N結束(瞭解便可)
8 
9 p.authkey:進程的身份驗證鍵,默認是由os.urandom()隨機生成的32字符的字符串。這個鍵的用途是爲涉及網絡鏈接的底層進程間通訊提供安全性,這類鏈接只有在具備相同的身份驗證鍵時才能成功(瞭解便可)

 

三、Process類的使用

注意:在windows中Process()必須放到# if __name__ == '__main__':下網絡

 

因爲Windows沒有fork,多處理模塊啓動一個新的Python進程並導入調用模塊。 
若是在導入時調用Process(),那麼這將啓動無限繼承的新進程(或直到機器耗盡資源)。 
這是隱藏對Process()內部調用的原,使用if __name__ == 「__main __」,這個if語句中的語句將不會在導入時被調用。

開啓子進程的方法一:

 

開啓子進程的方法二:併發

 

 

進程內存空間彼此隔離的例子:

 

 小練習:把以前所學的socket通信變成併發的形式:app

服務端:
 1 # _*_coding:utf-8_*_
 2 __author__ = 'huying'
 3 
 4 from socket import *
 5 
 6 from multiprocessing import Process
 7 
 8 server=socket(AF_INET,SOCK_STREAM)
 9 server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
10 server.bind(('127.0.0.1',8080))
11 server.listen(5)
12 
13 def talk(conn,client_addr):
14     while True:
15         try:
16             msg=conn.recv(1024)
17             if len(msg)==0:break
18             conn.send(msg.upper())
19         except Exception:
20             break
21 
22 if __name__ == '__main__':
23     while True:
24         conn,client_addr=server.accept()
25         p=Process(target=talk,args=(conn,client_addr))
26         p.start()
View Code

 

客戶端 :
# _*_coding:utf-8_*_
__author__ = 'huying'

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))

while True:
    msg=input('>>>:').strip()
    if len(msg)==0:continue
    phone.send(msg.encode('utf-8'))
    data=phone.recv(1024)
    print(data)
phone.close()
View Code

 

Process對象的join方法dom

  • join([time]): 等待至線程停止。這阻塞調用線程直至線程的join() 方法被調用停止-正常退出或者拋出未處理的異常-或者是可選的超時發生。

    以下:

     1 # _*_coding:utf-8_*_
     2 __author__ = 'huying'
     3 
     4 
     5 
     6 from multiprocessing import Process
     7 import time
     8 
     9 
    10 def task(name):
    11     print('%s is running.'%name)
    12     time.sleep(3)
    13     print('%s is done.'%name)
    14 
    15 if __name__ == '__main__':
    16     p=Process(target=task,args=('子進程1',))
    17     p.start()
    18     p.join()
    19     print('')
    View Code

    二、 socket

  

 1 from multiprocessing import Process
 2 import time
 3 def task(name,n):
 4     print('%s is running.'%name)
 5     time.sleep(n)
 6     print('%s is done.'%name)
 7 if __name__ == '__main__':
 8     p1=Process(target=task,args=('子進程1',1))
 9     p2=Process(target=task,args=('子進程2',2))
10     p3=Process(target=task, args=('子進程3', 3))
11 
12     start_time=time.time()
13     p1.start()
14     p2.start()
15     p3.start()
16 
17     p1.join()
18     p2.join()
19     p3.join()
20 
21     stop_time=time.time()
22     print('',(stop_time-start_time))
View Code

 

三、ide

 1 from multiprocessing import Process
 2 import time
 3 def task(name,n):
 4     print('%s is running.'%name)
 5     time.sleep(n)
 6     print('%s is done.'%name)
 7 
 8 if __name__ == '__main__':
 9     p1=Process(target=task,args=('子進程1',1))
10     p2=Process(target=task,args=('子進程2',2))
11     p3=Process(target=task,args=('子進程3',3))
12 
13     start=time.time()
14 
15     p1.start()
16     p1.join()
17     p2.start()
18     p2.join()
19     p3.start()
20     p3.join()
21 
22     stop=time.time()
23     print('',(stop-start))
View Code

 

四、  3的精簡版

 1 from multiprocessing import Process
 2 import time
 3 def task(name,n):
 4     print('%s is running.'%name)
 5     time.sleep(n)
 6     print('%s is done.'%name)
 7 
 8 if __name__ == '__main__':
 9     p_1=[]
10     start=time.time()
11     for i in range(1,4):
12         p=Process(target=task,args=('子進程%s'%i,i))
13         p_1.append(p)
14         p.start()
15 
16     for p in p_1:
17         p.join()
18 
19     stop=time.time()
20     print('',(stop-start))
View Code

 

瞭解知識點:

 1 #進程對象的其餘方法一:terminate,is_alive
 2 from multiprocessing import Process
 3 import time
 4 import random
 5 
 6 class Piao(Process):
 7     def __init__(self,name):
 8         self.name=name
 9         super().__init__()
10 
11     def run(self):
12         print('%s is piaoing' %self.name)
13         time.sleep(random.randrange(1,5))
14         print('%s is piao end' %self.name)
15 
16 
17 p1=Piao('egon1')
18 p1.start()
19 
20 p1.terminate()#關閉進程,不會當即關閉,因此is_alive馬上查看的結果可能仍是存活
21 print(p1.is_alive()) #結果爲True
22 
23 print('開始')
24 print(p1.is_alive()) #結果爲False
25 
26 terminate與is_alive
View Code

 

 1 from multiprocessing import Process
 2 import time
 3 import random
 4 class Piao(Process):
 5     def __init__(self,name):
 6         # self.name=name
 7         # super().__init__() #Process的__init__方法會執行self.name=Piao-1,
 8         #                    #因此加到這裏,會覆蓋咱們的self.name=name
 9 
10         #爲咱們開啓的進程設置名字的作法
11         super().__init__()
12         self.name=name
13 
14     def run(self):
15         print('%s is piaoing' %self.name)
16         time.sleep(random.randrange(1,3))
17         print('%s is piao end' %self.name)
18 
19 p=Piao('egon')
20 p.start()
21 print('開始')
22 print(p.pid) #查看pid
23 
24 name與pid
View Code
相關文章
相關標籤/搜索