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

Python程序中的進程操作-開啟多進

系統 1847 0

目錄

  • 一、multiprocess模塊
  • 二、multiprocess.process模塊
  • 三、process模塊介紹
    • 3.1 方法介紹
    • 3.2 屬性介紹
    • 3.3 在windows中使用process模塊的注意事項
  • 四、使用process模塊創建進程
    • 4.1 在Python中啟動的第一個子進程
    • 4.2 join方法
    • 4.3 查看主進程和子進程的進程號
    • 4.4 多個進程同時運行
    • 4.5 多個進程同時運行,再談join方法(1)
    • 4.6 多個進程同時運行,再談join方法(2)
    • 4.7 通過繼承Process類開啟進程
    • 4.8 進程之間的數據隔離問題
  • 五、守護進程
    • 5.1 守護進程的啟動
    • 5.2 主進程代碼執行結束守護進程立即結束
  • 六、socket聊天并發實例
    • 6.1 使用多進程實現socket聊天并發-server端
    • 6.2 使用多進程實現socket聊天并發-client端
  • 七、多進程中的其他方法
    • 7.1 進程對象的其他方法:terminate和is_alive
    • 7.2 進程對象的其他屬性:pid和name

之前我們已經了解了很多進程相關的理論知識,了解進程是什么應該不再困難了,剛剛我們已經了解了,運行中的程序就是一個進程。所有的進程都是通過它的父進程來創建的。因此,運行起來的python程序也是一個進程,那么我們也可以在程序中再創建進程。多個進程可以實現并發效果,也就是說,當我們的程序中存在多個進程的時候,在某些時候,就會讓程序的執行速度變快。以我們之前所學的知識,并不能實現創建進程這個功能,所以我們就需要借助python中強大的模塊。

一、multiprocess模塊

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

二、multiprocess.process模塊

process模塊是一個創建進程的模塊,借助這個模塊,就可以完成進程的創建。

三、process模塊介紹

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

強調:

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

參數介紹:

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

3.1 方法介紹

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

3.2 屬性介紹

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

3.3 在windows中使用process模塊的注意事項

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

四、使用process模塊創建進程

在一個python進程中開啟子進程,start方法和并發效果。

4.1 在Python中啟動的第一個子進程

          
            import time
from multiprocessing import Process

def f(name):
    print('hello', name)
    print('我是子進程')

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    time.sleep(1)
    print('執行主進程的內容了')
          
        

4.2 join方法

          
            import time
from multiprocessing import Process

def f(name):
    print('hello', name)
    time.sleep(1)
    print('我是子進程')


if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    # p.join()
    print('我是父進程')
          
        

4.3 查看主進程和子進程的進程號

          
            import os
from multiprocessing import Process

def f(x):
    print('子進程id :',os.getpid(),'父進程id :',os.getppid())
    return x*x

if __name__ == '__main__':
    print('主進程id :', os.getpid())
    p_lst = []
    for i in range(5):
        p = Process(target=f, args=(i,))
        p.start()
          
        

進階,多個進程同時運行(注意,子進程的執行順序不是根據啟動順序決定的)

4.4 多個進程同時運行

          
            import time
from multiprocessing import Process


def f(name):
    print('hello', name)
    time.sleep(1)


if __name__ == '__main__':
    p_lst = []
    for i in range(5):
        p = Process(target=f, args=('bob',))
        p.start()
        p_lst.append(p)
          
        

4.5 多個進程同時運行,再談join方法(1)

          
            import time
from multiprocessing import Process


def f(name):
    print('hello', name)
    time.sleep(1)


if __name__ == '__main__':
    p_lst = []
    for i in range(5):
        p = Process(target=f, args=('bob',))
        p.start()
        p_lst.append(p)
        p.join()
    # [p.join() for p in p_lst]
    print('父進程在執行')
          
        

4.6 多個進程同時運行,再談join方法(2)

          
            import time
from multiprocessing import Process

def f(name):
    print('hello', name)
    time.sleep(1)

if __name__ == '__main__':
    p_lst = []
    for i in range(5):
        p = Process(target=f, args=('bob',))
        p.start()
        p_lst.append(p)
    # [p.join() for p in p_lst]
    print('父進程在執行')
          
        

除了上面這些開啟進程的方法,還有一種以繼承Process類的形式開啟進程的方式

4.7 通過繼承Process類開啟進程

          
            import os
from multiprocessing import Process


class MyProcess(Process):
    def __init__(self,name):
        super().__init__()
        self.name=name
    def run(self):
        print(os.getpid())
        print('%s 正在和女主播聊天' %self.name)

p1=MyProcess('wupeiqi')
p2=MyProcess('yuanhao')
p3=MyProcess('nezha')

p1.start() # start會自動調用run
p2.start()
# p2.run()
p3.start()


p1.join()
p2.join()
p3.join()

print('主線程')
          
        

進程之間的數據隔離問題

4.8 進程之間的數據隔離問題

          
            from multiprocessing import Process

def work():
    global n
    n=0
    print('子進程內: ',n)


if __name__ == '__main__':
    n = 100
    p=Process(target=work)
    p.start()
    print('主進程內: ',n)
          
        

五、守護進程

會隨著主進程的結束而結束。

主進程創建守護進程

  其一:守護進程會在主進程代碼執行結束后就終止

  其二:守護進程內無法再開啟子進程,否則拋出異常: AssertionError: daemonic processes are not allowed to have children

注意: 進程之間是互相獨立的,主進程代碼運行結束,守護進程隨即終止。

5.1 守護進程的啟動

          
            import os
import time
from multiprocessing import Process

class Myprocess(Process):
    def __init__(self,person):
        super().__init__()
        self.person = person
    def run(self):
        print(os.getpid(),self.name)
        print('%s正在和女主播聊天' %self.person)


p=Myprocess('哪吒')
p.daemon=True # 一定要在p.start()前設置,設置p為守護進程,禁止p創建子進程,并且父進程代碼執行結束,p即終止運行
p.start()
time.sleep(10)  # 在sleep時查看進程id對應的進程ps -ef|grep id
print('主')
          
        

5.2 主進程代碼執行結束守護進程立即結束

          
            from multiprocessing import Process

def foo():
    print(123)
    time.sleep(1)
    print("end123")

def bar():
    print(456)
    time.sleep(3)
    print("end456")


p1=Process(target=foo)
p2=Process(target=bar)

p1.daemon=True
p1.start()
p2.start()
time.sleep(0.1)
print("main-------")  # 打印該行則主進程代碼結束,則守護進程p1應該被終止.#可能會有p1任務執行的打印信息123,因為主進程打印main----時,p1也執行了,但是隨即被終止.
          
        

六、socket聊天并發實例

6.1 使用多進程實現socket聊天并發-server端

          
            from socket import *
from multiprocessing import Process

server=socket(AF_INET,SOCK_STREAM)
server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
server.bind(('127.0.0.1',8080))
server.listen(5)

def talk(conn,client_addr):
    while True:
        try:
            msg=conn.recv(1024)
            if not msg:break
            conn.send(msg.upper())
        except Exception:
            break

if __name__ == '__main__': # windows下start進程一定要寫到這下面
    while True:
        conn,client_addr=server.accept()
        p=Process(target=talk,args=(conn,client_addr))
        p.start()
          
        

6.2 使用多進程實現socket聊天并發-client端

          
            from socket import *

client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8080))


while True:
    msg=input('>>: ').strip()
    if not msg:continue

    client.send(msg.encode('utf-8'))
    msg=client.recv(1024)
    print(msg.decode('utf-8'))
          
        

七、多進程中的其他方法

7.1 進程對象的其他方法:terminate和is_alive

          
            from multiprocessing import Process
import time
import random

class Myprocess(Process):
    def __init__(self,person):
        self.name=person
        super().__init__()

    def run(self):
        print('%s正在和網紅臉聊天' %self.name)
        time.sleep(random.randrange(1,5))
        print('%s還在和網紅臉聊天' %self.name)


p1=Myprocess('哪吒')
p1.start()

p1.terminate()#關閉進程,不會立即關閉,所以is_alive立刻查看的結果可能還是存活
print(p1.is_alive()) #結果為True

print('開始')
print(p1.is_alive()) #結果為False
          
        

7.2 進程對象的其他屬性:pid和name

          
            class Myprocess(Process):
    def __init__(self,person):
        self.name=person   # name屬性是Process中的屬性,標示進程的名字
        super().__init__()  # 執行父類的初始化方法會覆蓋name屬性
        # self.name = person  # 在這里設置就可以修改進程名字了
        # self.person = person  # 如果不想覆蓋進程名,就修改屬性名稱就可以了
    def run(self):
        print('%s正在和網紅臉聊天' %self.name)
        # print('%s正在和網紅臉聊天' %self.person)
        time.sleep(random.randrange(1,5))
        print('%s正在和網紅臉聊天' %self.name)
        # print('%s正在和網紅臉聊天' %self.person)


p1=Myprocess('哪吒')
p1.start()
print(p1.pid)    #可以查看子進程的進程id
          
        

更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 本溪市| 杭州市| 凌海市| 金寨县| 绵阳市| 卢龙县| 贞丰县| 平凉市| 平武县| 宁波市| 镶黄旗| 锡林浩特市| 安乡县| 黄陵县| 博白县| 固原市| 沈阳市| 赞皇县| 儋州市| 库尔勒市| 宁乡县| 墨竹工卡县| 芦山县| 谢通门县| 伊金霍洛旗| 龙门县| 高清| 南陵县| 洛宁县| 静宁县| 儋州市| 衡阳县| 乌拉特中旗| 祁门县| 焦作市| 桃园市| 中卫市| 商水县| 托克托县| 尼木县| 禹城市|