進程的相關知識
1,對多進程的模塊: multiprocess Process是進程的模塊
form multiprocessing import Process從multiprocessing包中導入Process模塊
multiprocess是python中的一個操作管理進程的一個包,multi是取自multiple的多功能的意思,在這個包中,幾乎包含了和進程操作的所有模塊,有與子模塊非常多,為了方便大家學習可以分為四個部分:創建進程部分,進程池部分,進程同步部分,進程之間數據共享
2,進程的並行與並發
2.1>並行:是指兩者同時執行,好比有2條車道,在某一時間點(比如說下午3:58)兩條車道上都有車在跑:(資源夠用,比如三線程,四核CPU)
2.2.>並發:是指資源有限的情況下,兩者交替輪流使用資源,比如只有一條車道(單核CPU資源),name就是A車先走,在某個時刻A車退出,把車道讓給B車,B車走完,繼續給A車使用
2.3>區別:並行是從微觀上,也就是在一個精確的時間片刻,有不同的成序在執行,這就要求必須要求有多個處理器
並發:是從微觀上來看,在一個時間段上可以看出是通同時執行,比如一個服務器同時處理多個session
註意:早期單核CPU的時候,對於進程也是微觀上串行(站在cpu角度看),宏觀上是並行(站在人的角度有喝多程序在執行,那是因為CPU處理速度太快,你感受不到)
2.4>同步:一個人物的完成任務時,需要依賴另一個,只有等待另一個任務完成時,依賴的任務才能算完成,這時一種可靠的任務序列,要麽成功都成功,失敗都失敗,兩個任務的狀態保持一致
2.5>異步:是不需要被等待的任務完成,只是通知被依賴的任務要完成什麽工作,依賴的任務也立即執行,只要自己完成了,整個任務就算完成了,至於被依賴的任務最終是否真正完成,依賴它 的任務無法完成,所以它是不可靠的任務序列
2.6>阻塞和非阻塞這兩個概念與程序等待消息通知是的狀態有關,也就是說阻塞與非阻塞主要是程序等待消息是的狀態的角度來說的
就緒狀態是在只要從新開始執行程序都會進入到就緒狀態(阻塞的時候和啟動程序的時候)
3,進程的開啟:
3.1>使用函數來開啟子進程
from multiprocessing impport Process......................導入Process這個模塊
import os ....................................導入os這個模塊
import time...................................導入時間模塊
def func(n):........................定義一個函數
time.sleep(1).....................休眠1秒
print("執行到我了...我的pid值是:%s,我父進程(主進程)的pid的只是:%s" %(os.getpid(),os.getppid()))....os.getpid()和os.getppid()是查找進程的pid值,每個運行的程序都會有一個獨立的pid值,os.getppid()是獲得父進程的pid值
if __name__ == "__main__":.................表示在windows系統當前模塊的__name == __main__的時候執行以下代碼
p = Process(target = func,args = (1,))..........Process其實是一個類,此時是實例化一個Process類的對象
p.start()..................是啟動一個子進程(是通過python解釋器發送給操作系統幫開一個子進程) 進程的就緒狀態
time.sleep(2)..........休眠2秒,此時如果子進程和父進程休眠時間不一樣,誰時間短就先執行誰,一樣的話就沒準了.
print("我是主進程...我自己的pid值是:%s,此時我的父進程的pid的值是:%s" % (os.getpid(),os.getppid()))
3.2>通過繼承的方式來開啟子進程
from multiProcessing import process
class MyProcess(Process):..............自定義一個類名但是要繼承Process類,因為Process裏有_popen屬性
def __init__(self):
super(MyProcess,self).__init__()............調用父類的__init__方法
print("執行到這了...")
def run(self):.......................定義一個run方法
print("這是以繼承類的方式開啟的子進程")
if __name__ == "__main__":......同樣的在windows操作系統中只有當模塊中的條件滿足執行以下帶代碼
p1 = MyProcess().....................實例化定義類的對象
p1.start()....開啟一個子進程(是通過python解釋器去告訴操作系統幫開一個子進程) 就緒狀態
p1.run()...............是直接幹預操作系統進而直接先執行Process中的run方法開啟一個子進程執行run方法
print("我是父進程...")
3.3>開啟多個子進程
from multiProcessing import Process
def func(n):
print("這是子進程%s"%n)
if __name__ == "__main__":
for i in range(3):................for循環是去開啟子進程的個數
p = Process(target=func,args =(i,)),....此時的target = 後邊跟的是上邊的函數名,args=後邊是for循環次數的參數
p.start()
print("這是父進程%s"%i)
3.4>通過集成的方式去開啟多個子進程
from multiprocess import Process
calss MyProcess(Process):
def __init__(self,count):
super(MyProcess,self).__init__():
self.count = count
def run(self):
print("這是子進程%s"%self.count)
if __name__ == "__main__":
for i in range(3):
p = MyProcess(i).................實例化對象去傳參數
p. start()
print("這裏是父進程%s"%i)
4,進程的其他常用操作
is_alive().................................判斷子進程是否在執行返回的值是bool值(在開啟子進程之後才能判斷是否活著)
terminate()...............................殺死進程(殺死的是子進程)殺子進程需要一定的時間,網絡傳輸就是有許多的不確定性
5,進程的start,和join
from multiprocessing import Process
def func():
for i in range(10):
time.sleep(0.02)
print("兒子在這裏")
if __name__ == "__main__":
p.start()
p.join().....................當join的時候就會把子進程運行完,再運行主進程(是異步變同步)主進程進行到到這就會阻塞
for i in range(5):
time,sleep(0.01)
print("爸爸在這裏")
當進的時候有多個子進程,也會等子進程全部運行完再執行主進程的代碼.
p.join是讓主進程等待子進程執行完,現象:主進程執行到這句話,主進程阻塞,等待子進程執行
父進程執行執行join,就會變成同步,不執行join,父進程和子進程就是異步的關系
join()必須放在start()的後邊
6,進程的長用屬性
6.1>從主進程獲得子進程的相關信息
from multiprocessing import Process
import os
def func():
print("這裏是子進程,我自己的pid值是%s"%os.getpid())
if __name__ == "__main__":
p = Process(target=func)
p.start()
p.name = "liangxue"...........................給當前這個子進程命名名字,當從新開啟一個進程可以再重新命名
print("子進程的名字時%s"%p.name)..................查詢這個名字
print("子進程的pid值是:%s"p.pid).....................此2獲得的daemon值是從子進程的os.getpid得來的
print("子進程是不是守護進程"p.daemon)......................False
6.2>守護進程(是在start(之前靜實例化的對象設置為守護進程))
from multiprocessing import Process
import time
def func():
time.sleep(0.1)
print("我是子程,同時我也是守護進程")
if __name__ == "__main__":
p = Process(target = func)
p.daemon = True...........此時表示將開啟的這個子進程設定為守護進程False是為正常進程,必須在開啟子進程之前進行,將接下來的子進程變為守護進程.daemon的默認值是False
p.start()
time.sleep(0.5)
print("我這裏是主進程")
守護進程的2個特點:
1>守護進程會隨著父進程結束而結束
2>守護進程不能再創建子進程
7,多個子進程之間無法共享內存
from multiprocessing import Process
import time
import random
def func(i):
print("我是%s"%i)
if __name__ =="__main__":
l = [ ]
addr = ["河南的","山東","遼寧的","湖南的"]
for i in addr:
p = Process(target=func,args=(i,))
p.start()
l.append(p)
[p.join() for p in l].........用列表推導式來同時join主四個子進程,目的就是等四個主進程都完畢了再執行主進程
time.sleep(1)
print("我選%s"%random.choice(addr)))等子進程都執行完畢後再執行主進程
每個子進程都是相對獨立的個體,他們之間的資源不能共享.join不能再for循環裏邊,要放到一個列表中再用列表推導式,一次join主等4個子進程全部完事以後,在執行主程序的代碼,效果是完全不一樣的
進程的相關知識