日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

112 Python程序中的進(jìn)程操作-開啟多進(jìn)

系統(tǒng) 1850 0

目錄

  • 一、multiprocess模塊
  • 二、multiprocess.process模塊
  • 三、Process類
    • 3.1 方法介紹
    • 3.2 屬性介紹
    • 3.3 在windows中使用Process類的注意事項
  • 四、process類的使用
    • 4.1 創(chuàng)建并開啟子進(jìn)程的兩種方式
    • 4.2 join方法
    • 4.3 查看主進(jìn)程和子進(jìn)程的進(jìn)程號
    • 4.4 查看進(jìn)程名和進(jìn)程狀態(tài)、設(shè)置進(jìn)程名
    • 4.5 terminate結(jié)束子進(jìn)程
    • 4.6 Process中的守護(hù)進(jìn)程
  • 五、socket聊天并發(fā)實例
    • 5.1 使用多進(jìn)程實現(xiàn)socket聊天并發(fā)-server端
    • 5.2 使用多進(jìn)程實現(xiàn)socket聊天并發(fā)-client端

運行中的程序就是一個進(jìn)程。 所有的進(jìn)程都是通過它的父進(jìn)程來創(chuàng)建的 。因此,運行起來的python程序也是一個進(jìn)程,那么我們也可以在程序中再創(chuàng)建進(jìn)程。多個進(jìn)程可以實現(xiàn)并發(fā)效果,當(dāng)我們的程序中存在多個進(jìn)程的時候,在某些時候,就會讓程序的執(zhí)行速度變快。

在linux c語言中創(chuàng)建線程使用的fork函數(shù),而Python就需要借助響應(yīng)的模塊

一、multiprocess模塊

仔細(xì)說來,multiprocess不是一個模塊而是python中一個操作、管理進(jìn)程的包。 之所以叫multi是取自multiple的多功能的意思,在這個包中幾乎包含了和進(jìn)程有關(guān)的所有子模塊。由于提供的子模塊非常多,為了方便大家歸類記憶,我將這部分大致分為四個部分:創(chuàng)建進(jìn)程部分,進(jìn)程同步部分,進(jìn)程池部分,進(jìn)程之間數(shù)據(jù)共享。

二、multiprocess.process模塊

process模塊是一個創(chuàng)建進(jìn)程的模塊,借助這個模塊,就可以完成進(jìn)程的創(chuàng)建。

三、Process類

Process([group [, target [, name [, args [, kwargs]]]]]) ,由該類實例化得到的對象,表示一個子進(jìn)程中的任務(wù)(尚未啟動)

強調(diào):

  1. 需要使用關(guān)鍵字的方式來指定參數(shù)
  2. args指定的為傳給target函數(shù)的位置參數(shù),是一個元組形式,必須有逗號

參數(shù)介紹:

  • group參數(shù)未使用,值始終為None
  • target表示調(diào)用對象,即子進(jìn)程要執(zhí)行的任務(wù)
  • args表示調(diào)用對象的位置參數(shù)元組, args=(1,2,'egon',)
  • kwargs表示調(diào)用對象的字典, kwargs={'name':'egon','age':18}
  • name為子進(jìn)程的名稱

3.1 方法介紹

  • p.start() :啟動進(jìn)程,并調(diào)用該子進(jìn)程中的p.run()
  • p.run() :進(jìn)程啟動時運行的方法,正是它去調(diào)用target指定的函數(shù),我們自定義類的類中一定要實現(xiàn)該方法
  • p.terminate() :強制終止進(jìn)程p,不會進(jìn)行任何清理操作,如果p創(chuàng)建了子進(jìn)程,該子進(jìn)程就成了僵尸進(jìn)程,使用該方法需要特別小心這種情況。如果p還保存了一個鎖那么也將不會被釋放,進(jìn)而導(dǎo)致死鎖
  • p.is_alive() :如果p仍然運行,返回True
  • p.join([timeout]) :主線程等待p終止(強調(diào):是主線程處于等的狀態(tài),而p是處于運行的狀態(tài))。timeout是可選的超時時間,需要強調(diào)的是,p.join只能join住start開啟的進(jìn)程,而不能join住run開啟的進(jìn)程

3.2 屬性介紹

  • p.daemon :默認(rèn)值為False,如果設(shè)為True,代表p為后臺運行的守護(hù)進(jìn)程,當(dāng)p的父進(jìn)程終止時,p也隨之終止,并且設(shè)定為True后,p不能創(chuàng)建自己的新進(jìn)程,必須在 p.start() 之前設(shè)置
  • p.name :進(jìn)程的名稱
  • p.pid :進(jìn)程的pid
  • p.exitcode :進(jìn)程在運行時為None、如果為–N,表示被信號N結(jié)束(了解即可)
  • p.authkey :進(jìn)程的身份驗證鍵,默認(rèn)是由 os.urandom() 隨機生成的32字符的字符串。這個鍵的用途是為涉及網(wǎng)絡(luò)連接的底層進(jìn)程間通信提供安全性,這類連接只有在具有相同的身份驗證鍵時才能成功(了解即可)

3.3 在windows中使用Process類的注意事項

在Windows操作系統(tǒng)中由于沒有fork(linux操作系統(tǒng)中創(chuàng)建進(jìn)程的機制),在創(chuàng)建子進(jìn)程的時候會自動 import 啟動它的這個文件,而在 import 的時候又執(zhí)行了整個文件。因此如果將process()直接寫在文件中就會無限遞歸創(chuàng)建子進(jìn)程報錯。所以必須把創(chuàng)建子進(jìn)程的部分使用 if __name__ =='__main__' 判斷保護(hù)起來,import 的時候,就不會遞歸運行了。

四、process類的使用

在一個python進(jìn)程中開啟子進(jìn)程,start方法和并發(fā)效果。

4.1 創(chuàng)建并開啟子進(jìn)程的兩種方式

  • 方式一:通過函數(shù)

                  
                    from multiprocessing import Process
    import time
    
    '''
    開啟子進(jìn)程的兩種方式:
    1. 通過函數(shù)
    2. 通過類。繼承Process
    '''
    
    def task(name):
        print("進(jìn)程{%s} start"%(name))
        time.sleep(2)
        print(f"進(jìn)程{name} end")
    
    # 必須加main
    if __name__ == '__main__':
        ######## 方式1(通過函數(shù))
        p = Process(target=task,args=("xc",))   # args用于傳參,是個元祖,必須加逗號
        p.start() # 告訴操作系統(tǒng)啟動子進(jìn)程,但一定是父進(jìn)程先執(zhí)行,多個子進(jìn)程的執(zhí)行順序是根據(jù)操作系統(tǒng)調(diào)度決定的
        print('主進(jìn)程/父進(jìn)程')
        print('主進(jìn)程/父進(jìn)程')
        p1 = Process(target=task,args=("cyx",))
        p1.start()  # 告訴操作系統(tǒng)啟動子進(jìn)程,但一定是父進(jìn)程先執(zhí)行,多個子進(jìn)程的執(zhí)行順序是根據(jù)操作系統(tǒng)調(diào)度決定的
        print('主進(jìn)程/父進(jìn)程')
        print('主進(jìn)程/父進(jìn)程')
        print('主進(jìn)程/父進(jìn)程')
        print('主進(jìn)程/父進(jìn)程')
                  
                
  • 方式二:通過類。繼承Process

                  
                    from multiprocessing import Process
    import time
    
    '''
    開啟子進(jìn)程的兩種方式:
    1. 通過函數(shù)
    2. 通過類。繼承Process
    '''
    
    class myProcess(Process):
        def __init__(self,name):
            # self.name = name #錯誤 ### 這樣沒有給對象添加屬性name,而是在修改父類的進(jìn)程名(name)
    
            # 父類Process的進(jìn)程名也是name
            super().__init__()  # 調(diào)用父類super().init方法完成創(chuàng)建進(jìn)程初始化,重新給name屬性賦值了。
            self.name = name    ## 在父類的init方法后設(shè)置name,才是為自己對象添加屬性
    
            # super().__init__(name=name)  # 調(diào)用父類super().init,并設(shè)置進(jìn)程名(name)
    
    
        def run(self):  # 創(chuàng)建進(jìn)程會默認(rèn)調(diào)用run方法
            print("進(jìn)程%s start" % (self.name))
            time.sleep(2)
            print(f"進(jìn)程{self.name} end")
    
    # 必須加main
    if __name__ == '__main__':
        p = myProcess("xc")
        p.start()
        print('主進(jìn)程/父進(jìn)程')
        print('主進(jìn)程/父進(jìn)程')
        p1 = myProcess("cyx")
        p1.start()  # 告訴操作系統(tǒng)啟動子進(jìn)程,但一定是父進(jìn)程先執(zhí)行,多個子進(jìn)程的執(zhí)行順序是根據(jù)操作系統(tǒng)調(diào)度決定的
        print('主進(jìn)程/父進(jìn)程')
        print('主進(jìn)程/父進(jìn)程')
        print('主進(jìn)程/父進(jìn)程')
        print('主進(jìn)程/父進(jìn)程')
                  
                

4.2 join方法

join方法用于回收子進(jìn)程

          
            from multiprocessing import Process
import time
  
def foo(x):
      print('進(jìn)程  start ')
      time.sleep(x)
      print('進(jìn)程  end ')
      
if __name__ == '__main__':
      ### 串行執(zhí)行和回收子進(jìn)程
      # p = Process(target=foo, args=(1,))
      # p2 = Process(target=foo, args=(2,))
      # p3 = Process(target=foo, args=(3,))
      # p.start() #
      # p.join() # 阻塞住主進(jìn)程再等待子進(jìn)程結(jié)束,然后再往下執(zhí)行,(了解的是:內(nèi)部會待用wait())
      # p2.start()
      # p2.join()
      # p3.start()
      # p3.join()
      # print('主')
  
      # 并發(fā)執(zhí)行進(jìn)程,并依次回收
      p = Process(target=foo, args=(1,))
      p2 = Process(target=foo, args=(2,))
      p3 = Process(target=foo, args=(3,))
      # 開啟進(jìn)程
      p.start()
      p2.start()
      p3.start()
  
      # 回收進(jìn)程
      p.join() # 阻塞住主進(jìn)程再等待子進(jìn)程結(jié)束,然后再往下執(zhí)行,(了解的是:內(nèi)部會待用wait())
      p2.join()
      p3.join()
      print('主')
          
        

4.3 查看主進(jìn)程和子進(jìn)程的進(jìn)程號

          
            from multiprocessing import Process,current_process
import time
import os
  
  '''
  查看主進(jìn)程和子進(jìn)程的進(jìn)程號
  1. 通過os.getpid()方法
  2. 通過multiprocessing模塊中的current_process().pid
  '''
  
  def task(name,x):
      print("當(dāng)前進(jìn)程pid:", current_process().pid)
      print(f"{name} start")
      time.sleep(x)
      print(f"{name} end")
  
  if __name__ == '__main__':
      p = Process(target=task,args=("進(jìn)程1",1))
      p.start()
      # 方式一
      print("子進(jìn)程pid:",p.pid)
      # 方式二
      # print("當(dāng)前進(jìn)程pid:",current_process().pid)
      print("當(dāng)前進(jìn)程pid",os.getpid())
      print("主進(jìn)程的父進(jìn)程pid",os.getppid())    # 實際上是pycharm的進(jìn)程號
      print()
          
        

4.4 查看進(jìn)程名和進(jìn)程狀態(tài)、設(shè)置進(jìn)程名

          
            '''
process設(shè)置名字: name屬性
process判斷進(jìn)程是否存在:is_alive
'''

from multiprocessing import Process
import time
  
  def task(x):
      print("進(jìn)程 start")
      time.sleep(x)
      print("進(jìn)程 end")
  
  if __name__ == '__main__':
      p = Process(target=task,args=(1,))
      p.start()
      p.name = "進(jìn)程1"
      print(p.name)
  
      print("子進(jìn)程是否存在:", p.is_alive()) # True
      time.sleep(2)   # 延時2秒等待子進(jìn)程結(jié)束
      print("子進(jìn)程是否存在:", p.is_alive()) # False
  
      print("主進(jìn)程")
          
        

4.5 terminate結(jié)束子進(jìn)程

          
            '''
terminate()
告訴子進(jìn)程讓他結(jié)束
'''

from multiprocessing import Process
import time
def task(x):
    print("進(jìn)程 start")
    time.sleep(x)
    print("進(jìn)程 end")

if __name__ == '__main__':
    p = Process(target=task,args=(10,))
    p.start()
    p.terminate()   # 告訴子進(jìn)程讓他提前結(jié)束

    p.name = "進(jìn)程1"
    print(p.name)

    print("子進(jìn)程是否存在:", p.is_alive()) # True
    p.join()
    print("子進(jìn)程是否存在:", p.is_alive()) # False

    print("主進(jìn)程")
          
        

4.6 Process中的守護(hù)進(jìn)程

首先,博主自己測試,實驗。Process中守護(hù)進(jìn)程的部分和真正的守護(hù)進(jìn)程概念并不一樣,因此只需要知道Process的守護(hù)進(jìn)程即可。

          
            '''
daemon = True 把子進(jìn)程變?yōu)槭刈o(hù)進(jìn)程
主進(jìn)程的代碼執(zhí)行完畢守護(hù)進(jìn)程直接結(jié)束。但如果子進(jìn)程代碼結(jié)束也會結(jié)束
'''
from multiprocessing import Process
import time
def task(x):
    print("進(jìn)程 start")
    time.sleep(x)
    print("進(jìn)程 end")


if __name__ == '__main__':
    p = Process(target=task,args=(2,))
    p.daemon = True  # 把子進(jìn)程變?yōu)槭刈o(hù)進(jìn)程
    p.start()
    # print(p.pid)

    p.name = "進(jìn)程1"
    print(p.name)
    print("子進(jìn)程pid:", p.pid) #

    print("子進(jìn)程是否存在:", p.is_alive()) # True
    time.sleep(3)
    print("子進(jìn)程是否存在:", p.is_alive()) # False

    print("主進(jìn)程")
    print("子進(jìn)程是否存在:", p.is_alive())  # False

    time.sleep(200)
          
        

五、socket聊天并發(fā)實例

5.1 使用多進(jìn)程實現(xiàn)socket聊天并發(fā)-server端

          
            import socket
from multiprocessing import Process

def talk(conn,client_addr):
    while 1:
            msg = conn.recv(1024)
            if not msg:
                break
            print(msg.decode("utf8"))
            conn.send(msg.upper())
            print(111)

if __name__ == '__main__':
    # 必須要寫在里面,不然會因為創(chuàng)建子線程重復(fù)調(diào)用導(dǎo)致端口被占用
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(("127.0.0.1", 8087))
    server.listen(5)

    while 1:
        print("等待連接")
        conn,addr = server.accept()
        print(addr,"連接成功")
        p = Process(target=talk,args=(conn,addr))
        p.start()
          
        

5.2 使用多進(jìn)程實現(xiàn)socket聊天并發(fā)-client端

          
            import socket

if __name__ == '__main__':
    client = socket.socket()
    client.connect(("127.0.0.1",8087))
    while 1:
        msg = input("請輸入內(nèi)容")
        client.send(msg.encode("utf8"))
        msg = client.recv(1024).decode("utf8")
        print(msg)
          
        

更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。。?/p>

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 建德市| 黄大仙区| 大同市| 嵩明县| 云浮市| 汉寿县| 连南| 苍南县| 铜陵市| 肥西县| 汶上县| 绩溪县| 平乐县| 阜南县| 溧水县| 清原| 永登县| 南开区| 易门县| 霞浦县| 镇安县| 剑河县| 毕节市| 托克逊县| 万盛区| 沙雅县| 六安市| 高唐县| 曲松县| 游戏| 稷山县| 岱山县| 六安市| 兰西县| 蒙城县| 太仓市| 隆德县| 阜康市| 荆门市| 梁山县| 大名县|