1. 程式人生 > >進程的相關知識

進程的相關知識

服務 3.3 無法 條件 解釋器 推導 內存 mce 三線程

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個子進程全部完事以後,在執行主程序的代碼,效果是完全不一樣的

    

      

  

    

    

      

          

進程的相關知識