一 進程:python
# 什麼是進程 : 運行中的程序,計算機中最小的資源分配單位
# 程序開始執行就會產生一個主進程
# python中主進程裏面啓動一個進程 —— 子進程
# 同時主進程也被稱爲父進程
# 父子進程之間的代碼執行是異步的,各自執行本身的
# 父子進程之間的數據不能夠共享
# 主進程會等待子進程結束以後再結束
二例子
#開啓一個子進程
1 import os 2 import time 3 from multiprocessing import Process 4 def func(num): 5 print(num,os.getpid()) 6 time.sleep(0.5) 7 print(num,os.getpid()) 8 time.sleep(0.5) 9 if __name__ == '__main__': 10 p=Process(target=func,args=(10,)) 11 p.start() 12 print(os.getpid(),0) 13 time.sleep(1) 14 print(os.getpid(),1)
##父進程和子進程數據不能夠共享,打印n爲100併發
1 n=100 2 def func(): 3 global n 4 n=0 5 print('------') 6 time.sleep(3) 7 if __name__ == '__main__': 8 Process(target=func).start() 9 time.sleep(1) 10 print(n) 11 12 13 結果:打印n爲100
#開啓多個子進程app
1 def func(n): 2 time.sleep(1) 3 print('_'*n) 4 if __name__ == '__main__': 5 l=[] 6 for i in range(10): 7 p=Process(target=func,args=(i,)) 8 p.start() 9 l.append(p) 10 11 print('子進程開始了') 12 for p in l:p.join() 13 print('10條信息已經發送完畢')
#守護進程dom
# 守護進程也是一個子進程
# 當主進程的代碼執行完畢以後自動結束的子進程叫作守護進程
#當主進程結束的時候守護進程才結束
例子一:
1 def deamon_func(): #守護進程 2 while True: 3 print('我還活着') 4 time.sleep(0.5) 5 def wahaha():#子進程 6 for i in range(10): 7 time.sleep(1) 8 print(i*'#') 9 if __name__ == '__main__': 10 p2=Process(target=wahaha) 11 p2.start() 12 p=Process(target=deamon_func) #守護進程 13 p.daemon=True 14 p.start() 15 for i in range(3): #主進程 16 print(i*'*') 17 time.sleep(1)
當主進程執行完以後,deamon_func也就中止打印了
1 def deamon_func(): 2 while True: 3 print('我還活着') 4 time.sleep(0.5) 5 def wahaha(): 6 for i in range(10): 7 time.sleep(1) 8 print(i*'#') 9 if __name__ == '__main__': 10 p2=Process(target=wahaha) 11 p2.start() 12 p=Process(target=deamon_func) #這個是守護進程 13 p.daemon=True 14 p.start() 15 for i in range(3): #主進程 16 print(i*'##') 17 time.sleep(1) 18 p2.join()
這個是當wahaha裏面的執行完畢了,守護進程才結束
總結異步
# 開啓一個子進程 start
# 子進程和主進程是異步
# 若是在主進程中要等待子進程結束以後再執行某段代碼:join
# 若是有多個子進程 不能在start一個進程以後就馬上join,把全部的進程放到列表中,等待全部進程都start以後再逐一join
# 守護進程 —— 當主進程的"代碼"執行完畢以後自動結束的子進程叫作守護進程
二 進程池
#提交任務的兩種方式:
#同步調用:提交完任務後,就在原地等待,等待任務執行完畢,拿到任務的返回值,才能繼續下一行代碼,致使程序串行執行
#異步調用+回調機制:提交完任務後,不在原地等待,任務一旦執行完畢就會觸發回調函數的執行, 程序是併發執行
#異步調用
1 from concurrent.futures import ProcessPoolExecutor
2 def task(n): 3 print('%s is runing'%os.getpid()) 4 time.sleep(random.randint(1,3)) 5 return n**2 6 def handle(res): 7 res=res.result() 8 print('handle res %s' %res) 9 if __name__ == '__main__': 10 pool=ProcessPoolExecutor(2) #開啓2個進程,每次執行2個 11 for i in range(5): 12 obj=pool.submit(task,i) 13 obj.add_done_callback(handle) 14 15 pool.shutdown() 16 print('主') 17 18 打印結果:12800 is runing 19 6264 is runing 20 6264 is runing 21 handle res 1 22 12800 is runing 23 handle res 0 24 6264 is runing 25 handle res 4 26 handle res 16 27 handle res 9 28 主
#同步調用,從上到下依次執行
1 from concurrent.futures import ProcessPoolExecutor
2 def task(n): 3 print('%s is runing'%os.getpid()) 4 time.sleep(random.randint(1,3)) 5 return n**2 6 def handle(res): 7 print('handle res %s' %res) 8 if __name__ == '__main__': 9 pool=ProcessPoolExecutor(3) 10 for i in range(5): 11 res=pool.submit(task,i).result() 12 handle(res) 13 pool.shutdown() 14 print('主') 15 16 執行結果: 17 16128 is runing 18 handle res 0 19 17120 is runing 20 handle res 1 21 7060 is runing 22 handle res 4 23 16128 is runing 24 handle res 9 25 17120 is runing 26 handle res 16 27 主
三 socketserver(用的就是多進程)
服務端:
1 import time 2 import socketserver 3 class Myserver(socketserver.BaseRequestHandler): 4 def handle(self): 5 conn = self.request 6 print(conn) 7 time.sleep(3) 8 conn.send(b'hello') 9 time.sleep(5) 10 conn.send(b'hello2') 11 # socketserver 12 # socket 13 14 myserver = socketserver.ThreadingTCPServer(('127.0.0.1',9000),Myserver) 15 myserver.serve_forever() 16 17 # socketserver所啓動的服務端是不能有input操做的 18 # server端通常都是根據client端的要求去執行固定的代碼
客戶端:socket
1 import socket 2 sk=socket.socket() 3 sk.connect(('127.0.0.1',9000)) 4 print(sk.recv(1024)) 5 print(sk.recv(1024)) 6 sk.close()