Python學習筆記九
Python學習筆記之九
為什么要有操作系統
管理硬件,提供接口。
管理調度進程,并且將多個進程對硬件的競爭變得有序。
操作系統發展史
第一代計算機:真空管和穿孔卡片
沒有操作系統,所有的程序設計直接操控硬件
優點:程序員獨享整個資源
缺點:浪費資源
第二代計算機:晶體管和批處理系統
優點:計算機資源利用
缺點:程序員共享資源,出現問題,找不出問題,影響開發效率
第三代計算機:集成電路芯片和多道程序設計
多道程序:cpu執行程序的過程中遇到I/O,不會原地等待,cpu會去執行其他命令,等到程序執行完I/O.(時間上的復用)
實現一個看起來像并發。CPU隨時切換進程。會影響CPU執行效率。
進程占用一個內存空間,每個進程的內存空間,是隔離的。(空間上的復用)
第四代計算機:個人計算機
多道技術:
產生背景:針對單核,實現并發。
空間復用:內存空間是隔離的
時間復用:遇到I/O就切,提高效率
遇到運行時間過長,不提高效率
并發與并行
并發:偽并行,單個CPU+多道技術,看起來像同時運行。
并行:多個CPU才能實現并行
windows和linux創建進程:
windows: createprocess創建進程的接口
linux: fork創建進程的接口
創建子進程:
linux:子進程是父進程的完整副本,
windows:父進程與子進程的內存地址有所不同
進程狀態:
運行
阻塞:碰到I/O,便要讓出CPU讓其他進程執行,保證CPU一直在工作。
就緒:時刻準備著運行

開啟進程的兩種方式:
為什么開啟子進程就實現了并發?
開啟子進程就為了執行自己的任務,而不會因為父進程阻塞,而影響自己。
開啟子進程的第一種方法:
from multiprocessing import Process
import time,random def piao (name): print('%s is piaoing' %name) # time.sleep(3000) if __name__ == '__main__': # p=Process(target=piao,args=('alex',)) p=Process(target=piao,kwargs={'name':'alex'}) p.start() #向操作系統發送開啟子進程的信號 # p.join() print ('主進程')
結果:
"D:\Program Files\Python36\python.exe" C:/Users/yangjianbo/PycharmProjects/untitled/第九課并發編程/開啟子進程.py
主進程
alex is piaoing
結論:
p.start() 只是向操作系統發出一個開啟子進程的信號,而不是真正的開啟子進程。
當p.start()執行完以后,會立刻執行下一行代碼,也就是print(),而不是等待子進程執行后,再執行print().
p.start()只能執行一次,多次會有報錯。
上面的例子:如果我想要子進程執行完畢以后,再執行print(),如何實現?
子進程執行完,再執行主進程的代碼。
from multiprocessing import Process import time,random def piao (name): print('%s is piaoing' %name) # time.sleep(3000) if __name__ == '__main__': # p=Process(target=piao,args=('alex',)) p=Process(target=piao,kwargs={'name':'alex'}) p.start() #向操作系統發送開啟子進程的信號 p.join() print ('主進程')
結果:
"D:\Program Files\Python36\python.exe" C:/Users/yangjianbo/PycharmProjects/untitled/第九課并發編程/開啟子進程.py
alex is piaoing
主進程
結論:在p.start()后面添加一個p.join(),主進程就會在當前位置停下,等待子進程運行完成,再執行后面的代碼。p.join()必須在p.start()的后面,否則子進程還未開啟,p.join()也沒有意義。這么做的意義就是為了防止主進程突然關閉,而導致子進程執行完畢以后,成為了僵尸進程。
開啟子進程的第二種方法:
采用自定義類的方式。
from multiprocessing import Process import time,random class Myprocess(Process): def __init__(self,name): super(Myprocess,self).__init__() self.name=name def run(self): print ('%s is piaoing' %self.name) if __name__ == '__main__': p=Myprocess('alex') p.start() print('主')
套接字通信開啟子進程
服務端:
from socket import socket from multiprocessing import Process def tongxin(conn,addr): while True: try: cmd = conn.recv(1024) # 收消息,限制單個消息的最大數為1024字節 if not cmd: break conn.send(cmd.upper()) except ConnectionResetError: break conn.close() def lianjie(): s = socket() s.bind(('127.0.0.1', 8080)) # 插卡,指定服務器的IP地址和端口號 s.listen(5) while True: conn, client_addr = s.accept() p=Process(target=tongxin,args=(conn,client_addr)) p.start() s.close() if __name__ == '__main__': lianjie()
客戶端:
import socket client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1',8080)) #打電話 while True: cmd=input('數據>>').strip() if not cmd:continue client.send(cmd.encode('utf-8')) #發消息 recv=client.recv(1024).decode('gbk') #收消息 print(recv) client.close()
進程對象的其他方法:
join方法:
from multiprocessing import Process import time,random def piao (name): print('%s is piaoing' %name) if __name__ == '__main__': p1=Process(target=piao,args=('alex',)) p2=Process(target=piao,args=('egon',)) p3 = Process(target=piao, args=('wupaiqi',)) p1.start() p2.start() p3.start() p1.join() p2.join() p3.join() print ('主進程')
結果:
"D:\Program Files\Python36\python.exe" C:/Users/yangjianbo/PycharmProjects/untitled/第九課并發編程/進程的其他對象方法.py
egon is piaoing
alex is piaoing
wupaiqi is piaoing
主進程
結論:
三個start()都是隨機開啟的,不會按順序啟動的。
三個join要放在三個start的后面,這樣才是并發。
from multiprocessing import Process import time,random def piao (name): print('%s is piaoing' %name) if __name__ == '__main__': p1=Process(target=piao,args=('alex',)) p2=Process(target=piao,args=('egon',)) p3 = Process(target=piao, args=('wupaiqi',)) p1.start() p1.join() p2.start() p2.join() p3.start() p3.join() # p1.join() # p2.join() # p3.join() print ('主進程')
結果:
"D:\Program Files\Python36\python.exe" C:/Users/yangjianbo/PycharmProjects/untitled/第九課并發編程/進程的其他對象方法.py
alex is piaoing
egon is piaoing
wupaiqi is piaoing
主進程
結論:
如果是這么寫的,就是真正的串行。
from multiprocessing import Process import time,random def piao (name): print('%s is piaoing' %name) if __name__ == '__main__': p1=Process(target=piao,args=('alex',)) p2=Process(target=piao,args=('egon',)) p3 = Process(target=piao, args=('wupaiqi',)) p_l=[p1,p2,p3] for p in p_l: p.start() for p in p_l: p.join() print ('主進程')
進程之間的內存空間是隔離的
from multiprocessing import Process n=100 def task(): global n n=0 print (n) if __name__ == '__main__': p=Process(target=task) p.start() p.join() print('主',n)
結果:
"D:\Program Files\Python36\python.exe" C:/Users/yangjianbo/PycharmProjects/untitled/第九課并發編程/進程之間的內存空間是隔離的.py
0
主 100
結論:
進程之間的內存空間是隔離的,因為我修改了子進程的n,但是主進程的n還是原來的。
查看進程的pid和ppid。
殺死進程
進程池

浙公網安備 33010602011771號