在python程序中的進程操做

********在python程序中的進程操做********

以前咱們已經瞭解了不少進程相關的理論知識,瞭解進程是什麼應該再也不困難了,剛剛咱們已經瞭解了,
運行中的程序就是一個進程。全部的進程都是經過它的父進程來建立的。所以,運行起來的python程序
也是一個進程,那麼咱們也能夠在程序中再建立進程。多個進程能夠實現併發效果,也就是說,當咱們的
程序中存在多個進程的時候,在某些時候,就會讓程序的執行速度變快。以咱們以前所學的知識,並不能
實現建立進程這個功能,因此咱們就須要藉助python中強大的模塊。

****multiprocessing模塊****

 仔細說來,multiprocess不是一個模塊而是python中一個操做、管理進程的包。 之因此叫multi是
 取自multiple的多功能的意思,在這個包中幾乎包含了和進程有關的全部子模塊。因爲提供的子模塊非
 常多,爲了方便你們歸類記憶,我將這部分大體分爲四個部分:建立進程部分,進程同步部分,進程池
 部分,進程之間數據共享。


#由該類實例化獲得的對象,表示一個子進程中的任務(還沒有啓動)
class Process(object):
    def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
        self.name = ''
        self.daemon = False
        self.authkey = None
        self.exitcode = None
        self.ident = 0
        self.pid = 0
        self.sentinel = None

    def run(self):
        pass

    def start(self):
        pass

    def terminate(self):
        pass

    def join(self, timeout=None):
        pass

    def is_alive(self):
        return False

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

參數介紹:
1.group參數未使用,值始終爲None
2.target表示調用的對象,即子進程要執行的任務
3.args表示調用對象的位置參數元組
4.kwargs表示調用對象的字典
5.name爲子進程的名稱


方法介紹:
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. p.daemon:默認值爲False,若是設爲True,表明p爲後臺運行的守護進程,當p的父進程終止時,p也隨之終止。
而且設定爲True後,p不能建立本身的新進程,必須在p.start()以前設置。
2. p.name:進程的名稱
3. p.pid:進程的pid
4. p.exitcode:進程在運行時爲None,若是爲-N,表示被信號N結束了
5. p.authkey:進程的身份驗證鍵,默認是由os.urandom()隨機生成的32字符的字符串。這個鍵的用途是爲涉及網
絡鏈接的底層進程間通訊提供安全性,這類鏈接只有在具備相同的身份驗證鍵時才能成功


在Windows中使用process模塊的注意事項
在Windows操做系統中因爲沒有fork(linux操做系統中建立進程的機制),在建立子進程的時候會自動 import 啓
動它的這個文件,而在 import 的時候又執行了整個文件。所以若是將process()直接寫在文件中就會無限遞歸創
建子進程報錯。因此必須把建立子進程的部分使用if __name__ ==‘__main__’ 判斷保護起來,import 的時候 ,
就不會遞歸運行了。


**使用Process模塊建立進程

方式一

from multiprocessing import Process
import os
import time


def func(s):
    print(s)
    print('子進程pid:%s', os.getpid())  # 獲取進程id
    print('子進程ppid:%s', os.getppid())  # 獲取進程父親id


if __name__ == '__main__':
    p = Process(target=func, args=('Tome',))
    p.start()
    time.sleep(1)
    print('主進程pid:%s', os.getpid())


方式二

from multiprocessing import Process


class MyProcess(Process):
    def __init__(self, na):
        self.na = na
        super().__init__()  # 必須繼承init  由於Process有一些屬性有本身的功能

    def run(self):
        print('我是%s' % self.na)
        print('這裏是子進程!')


if __name__ == '__main__':
    p = MyProcess('Tone')
    p.start()  # 是指,解釋器告訴系統,去幫我開啓一個進程   就緒狀態


jion方法

from multiprocessing import Process
import time


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


if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    # p.join()  #感知一個子進程的結束,將異步變同步
    print('我是父進程')


進程之間的數據隔離問題

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)


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

**多個進程同時運行

方式一
import time
from multiprocessing import Process


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


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

方式二

import time
from multiprocessing import Process


class MyProcess(Process):

    def __init__(self, na):
        super().__init__()
        self.na = na

    def run(self):
        print('hello', self.na)
        time.sleep(1)


if __name__ == '__main__':
    p_lst = []
    for i in range(5):
        p = MyProcess('Tom')
        p.start()
        p_lst.append(p)



**多個進程同時運行,再談join方法(1import time
from multiprocessing import Process


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


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


**多個進程同時運行,在談join方法(2import time
from multiprocessing import Process


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


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


****守護進程****

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

主進程建立守護進程

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

  其二:守護進程內沒法再開啓子進程,不然拋出異常:AssertionError: daemonic processes are not allowed to have children

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


例子:
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('Tom')
p.daemon = True  # 必定要在p.start()前設置,設置p爲守護進程,禁止p建立子進程,而且父進程代碼執行結束,p即終止運行
p.start()
time.sleep(10)  # 在sleep時查看進程id對應的進程ps -ef|grep id
print('主進程')


from multiprocessing import Process
import time


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也執行了,可是隨即被終止.


****多進程中的其餘方法****


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('Tom')
p1.start()

p1.terminate()#關閉進程,不會當即關閉,因此is_alive馬上查看的結果可能仍是存活
print(p1.is_alive()) #結果爲True

print('開始')
print(p1.is_alive()) #結果爲False
相關文章
相關標籤/搜索