1.進程: 進程(Process)是電腦中的程式關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。在早期面向進程設計的電腦結構中,進程是程式的基本執行實體;在當代面向線程設計的電腦結構中,進程是線程的容器。程式是指令、數據及其組織形式的描述,進程是程式的 ...
1.進程:
進程(Process)是電腦中的程式關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。在早期面向進程設計的電腦結構中,進程是程式的基本執行實體;在當代面向線程設計的電腦結構中,進程是線程的容器。程式是指令、數據及其組織形式的描述,進程是程式的實體。我們自己在python文件中寫了一些代碼,這叫做程式,運行這個python文件的時候,這叫做進程。
狹義定義:進程是正在運行的程式的實例(an instance of a computer program that is being executed)
廣義定義:進程是一個具有一定獨立功能的程式關於某個數據集合的一次運行活動。它是操作系統動態執行的基本單元,在傳統的操作系統中,進程既是基本的分配單元,也是基本的執行單元。
舉例:比如py1文件中有個變數a=1,py2文件中有個變數a=2,他們兩個會衝突嗎?不會的,因為兩個文件運行起來後是兩個進程,操作系統讓他們在記憶體上隔離開。
2.併發、並行:
併發:是偽並行,即看起來是同時運行。單個cpu+多道技術就可以實現併發,(並行也屬於併發)
並行:並行:同時運行,只有具備多個cpu才能實現並行
3.同步/非同步 與 阻塞和非阻塞:
1.進程狀態介紹:
(1)就緒(Ready)狀態:當進程已分配到除CPU以外的所有必要的資源,只要獲得處理機便可立即執行,這時的進程狀態稱為就緒狀態。
(2)執行/運行(Running)狀態當進程已獲得處理機,其程式正在處理機上執行,此時的進程狀態稱為執行狀態。
(3)阻塞(Blocked)狀態正在執行的進程,由於等待某個事件發生而無法執行時,便放棄處理機而處於阻塞狀態。引起進程阻塞的事件可有多種,例如,等待I/O完成、申請緩衝區不能滿足、等待信件(信號)等。
事件請求:input、sleep、文件輸入輸出、recv、accept
事件發生:sleep、input等完成了
時間片到了之後有回到就緒狀態,這三個狀態不斷的在轉換
2.同步/非同步 與 阻塞和非阻塞:
(1)同步阻塞形式:效率最低。拿上面的例子來說,就是你專心排隊,什麼別的事都不做。
(2)非同步阻塞形式:如果在排隊取餐的人採用的是非同步的方式去等待消息被觸發(通知),也就是領了一張小紙條,假如在這段時間里他不能做其它的事情,就在那坐著等著,不能玩游戲等,那麼很顯然,這個人被阻塞在了這個等待的操作上面;
(3)同步非阻塞形式:實際上是效率低下,想象一下你一邊打著電話一邊還需要抬頭看到底隊伍排到你了沒有,如果把打電話和觀察排隊的位置看成是程式的兩個操作的話,這個程式需要在這兩種不同的行為之間來回的切換,效率可想而知是低下的。
(4)非同步非阻塞形式:效率更高,因為打電話是你(等待者)的事情,而通知你則是櫃臺(消息觸發機制)的事情,程式沒有在兩種不同的操作中來回切換。
如,這個人突然發覺自己煙癮犯了,需要出去抽根煙,於是他告訴點餐員說,排到我這個號碼的時候麻煩到外面通知我一下,那麼他就沒有被阻塞在這個等待的操作上面,自然這個就是非同步+非阻塞的方式了。
4.multiprocessing模塊(包) Process模塊:
準確的說,multiprocess不是一個模塊而是python中一個操作、管理進程的包。 之所以叫multi是取自multiple的多功能的意思,在這個包中幾乎包含了和進程有關的所有子模塊。
process模塊是一個創建進程的模塊,藉助這個模塊,就可以完成進程的創建
Process類中參數的介紹:
1 group參數未使用,值始終為None
2 target表示調用對象,即子進程要執行的任務
3 args表示調用對象的位置參數元組,args=(1,2,'egon',)
4 kwargs表示調用對象的字典,kwargs={'name':'egon','age':18}
5 name為子進程的名稱
Process類中的方法介紹:
1 p.start():啟動進程,並調用該子進程中的p.run()
2 p.run():進程啟動時運行的方法,正是它去調用target指定的函數,我們自定義類的類中一定要實現該方法
3 p.terminate():強制終止進程p,不會進行任何清理操作,如果p創建了子進程,該子進程就成了僵屍進程,使用該方法需要特別小心這種情況。如果p還保存了一個鎖那麼也將不會被釋放,進而導致死鎖
4 p.is_alive():如果p仍然運行,返回True
5 p.join([timeout]): 主線程等待p終止(強調:是主線程處於等的狀態,而p是處於運行的狀態)。timeout是可選的超時時間,需要強調的是,p.join只能join住start開啟的進程,而不能join住run開啟的進程
1 import time 2 from multiprocessing import Process 3 4 5 def func1(n,m): 6 print('我是func1') 7 print('我是%s'%n) 8 time.sleep(1) 9 print(m) 10 11 12 def func2(): 13 time.sleep(2) 14 print('我是func2') 15 16 17 if __name__ == '__main__': 18 # target表示調用對象,即子進程要執行的任務 19 # args表示調用對象的位置參數元組,args = (1, 2,) 20 # kwargs表示調用對象的字典,kwargs={'name':'egon','age':18} 21 22 # p1 = Process(target=func1,args=(10,20,)) 23 p1 = Process(target=func1,kwargs={'n':10,'m':20}) 24 p2 = Process(target=func2) 25 26 p1.start() 27 p2.start() 28 print('主程式運行到這裡了') 29 p1.join() # 阻塞,等待1號子程式運行結束 30 p2.join() # 等待2號子程式運行結束 31 print('主程式運行結束')實例代碼
5.進程的兩種創建方法和隔離驗證
兩種創建方法
1 import time 2 from multiprocessing import Process 3 4 5 def func1(): 6 print('我是func1') 7 8 # 直接創建 9 # p = Process(target=func1) 10 # p.start() 11 12 13 # 面向對象方式創建 14 class MyProcess(Process): # 自定義對象創建進程必須繼承Process父類 15 def __init__(self,n): 16 super().__init__() # super()拿到父類的__init__()避免重置父類 17 self.n = n 18 19 def run(self): # 必須有run方法,沒有雖不會報錯,但父類run里是pass,不重寫run則為空 20 time.sleep(2) 21 print(self.n) 22 23 24 if __name__ == '__main__': # Windows下必須寫這句 避免重覆調用 25 p = MyProcess(10) 26 p.start() 27 28 print('主進程結束')
進程之間的隔離驗證
1 import time 2 from multiprocessing import Process 3 4 num = 100 5 def func(): 6 global num 7 num = 66 8 print('我是func>>>',num) 9 10 11 if __name__ == '__main__': 12 13 # 所有的子進程非同步執行 14 p_list = [] 15 for i in range(10): 16 p = Process(target=func) 17 p.start() 18 p.join() 19 p_list.append(p) 20 21 for pp in p_list: 22 pp.join() 23 24 # 所有的子進程全部執行完之後,再執行主進程(主進程運行很快),值不一樣則證明空間隔離 25 # time.sleep(1) # 用sleep 等子程式執行完也可 26 print('主程式num:',num) 27 print('主程式執行結束')
6.進程對象的其他方法瞭解:
terminate,is_alive
1 # 進程對象的其他方法一:terminate,is_alive 2 from multiprocessing import Process 3 import time 4 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 打飛機' %self.name) 13 # s = input('???') # 別忘了pycharm下子進程中不能input輸入,會報錯EOFError: EOF when reading a line,因為子進程中沒有像我們主進程這樣的在pycharm下的控制台可以輸入東西的地方 14 time.sleep(2) 15 print('%s is 打飛機結束' %self.name) 16 17 18 if __name__ == '__main__': 19 p1 = Piao('太白') 20 p1.start() 21 time.sleep(3) 22 p1.terminate() # 關閉進程,不會立即關閉,有個等著操作系統去關閉這個進程的時間,所以is_alive立刻查看的結果可能還是存活,但是稍微等一會,就被關掉了 23 print(p1.is_alive()) # 可能結果為True 24 print('等會。。。。') 25 time.sleep(1) 26 print(p1.is_alive()) # 結果一定為Falseterminate,is_alive
name pid
1 from multiprocessing import Process 2 import time 3 import random 4 5 6 class Piao(Process): 7 def __init__(self,name): 8 # self.name=name 9 # super().__init__() #Process的__init__方法會執行self.name=Piao-1, 10 # #所以加到這裡,會覆蓋我們的self.name=name 11 12 # 為我們開啟的進程設置名字的做法 13 super().__init__() 14 self.name=name 15 16 def run(self): 17 print('%s is piaoing' %self.name) 18 time.sleep(random.randrange(1,3)) 19 print('%s is piao end' %self.name) 20 21 22 if __name__ == '__main__': 23 24 p = Piao('egon') 25 p.start() 26 print('開始') 27 print(p.pid) # 查看pid 28 print(p.name) # 查看namename pid