獲取進程id和名字[getpid()--is_terminate()]--結束進程和判斷運行[is_alive()--is_alive]--守護線程[daemon()]--進程鎖[Lock()]--隊

1、如何獲取進程的id號和進程的名字.安全

os.getpid() #獲取本進程的id號併發

os.getppid() #獲取本進程的父進程的id號app

import os
from multiprocessing import Process
def f1():
    print('f1進程的pid',os.getpid())
    print('f1進程的父進程的pid',os.getppid())
if __name__ == '__main__':
    p1 = Process(target=f1,name='歡迎')
    p1.start()
    print(p1.name)
    print('p1進程的pid',p1.pid)
    print('本進程的id',os.getpid())
# p1.pid #返回結果爲p1進程的id號
# os.getpid()#返回本進程的id號
# os.getppid()#返回爲本進程的父進程id號
# p1.name()#返回p1進程的名字

 

2、如何手動結束子進程,以及判斷子進程是否還在運行ui

obj.is_terminate()  #給操做系統發送結束進程的信號spa

obj.is_alive()  #判斷進程是否在運行,返回值True,False操作系統

import time
from multiprocessing import Process
def f1():
    print('子進程1號')
if __name__ == '__main__':
    p = Process(target=f1,)
    p.start()
    print(p.is_alive())  #判斷子進程是否還活着,是否還在運行
    p.terminate() #給操做系統發送一個結束進程的信號
    time.sleep(0.5) #須要延遲一會再判斷是否還存活,由於系統結束進程須要處理不少東西
    print(p.is_alive())

 

3、如何驗證進程存在空間隔離code

對於打印結果的解釋:首先程序自上往下走,先打印一遍100,開啓子進程後,系統copy一份代碼走,並運行,又打印一遍100,子進程修改的只是本身進程裏的全局變量,對象

而父進程的變量仍是那個,這就驗證了進程之間存在空間隔離.blog

from multiprocessing import Process
num = 100
def f1():
    global num
    num = 3  #修改全局變量的值
    print('f1進程中的num',num)
print('>>>>>',num)
if __name__ == '__main__':
    p = Process(target=f1,)
    p.start()
    p.join()
    print('主進程中的num',num)
打印結果爲:
>>>>> 100
>>>>> 100
f1進程中的num 3
主進程中的num 100

4、關於守護進程隊列

obj(進程的實例化對象).daemon = True       #開啓守護進程,必定要在開啓進程( obj.start() )前設置
什麼是守護進程:
  1.在主進程代碼執行結束後就終止(應用場景:子進程須要跟父進程一塊兒結束時)
  2.守護進程內沒法開啓子進程,不然拋異常

 

from multiprocessing import Process
def f1():
    print("xxx")
def f2():
    print("p普通子進車")
if __name__ == '__main__':
    p = Process(target = f1,)
    p.daemon = True  #開啓守護進程,必定要在開啓該進程(p.start())前設置,父進程代碼執行結束,這個守護進程也結束.
    p.start()
    #p.join()  #給主進程阻塞,守護進程有機會執行裏面的代碼
    print("主進程結束.")
    p2 = Process(target = f2,) #普通進程不受限制
    p2.start()

5、關於殭屍進程和孤兒進程概念

殭屍進程:在子進程執行完,而主進程尚未執行完的時候,系統會保留執行的子進程一些信息(id號,名字...),它會隨着主進程的結束而被清理掉

孤兒進程:主進程在子進程前結束了,這個時候該子進程的一些信息沒人管了,就叫孤兒進程,最後會被系統清理.

6、關於互斥鎖\進程鎖\同步鎖:

什麼時進程所\互斥鎖\同步鎖:  控制進程在共享一個文件,或同一個打印終端的時候,產生競爭時的錯亂.原理是把併發改爲串行
with obj(鎖的實例化對象): #簡易寫法
  須要上鎖的代碼

Lock.acquire() #加鎖
Lock.release() #解鎖

 

from multiprocessing import Process,Lock
import time
def show_t(i):
    with open("ticket","r",encoding = "utf-8")as f:  #用with open打開文件,前2個能夠用位置參數,但第三個必須用關鍵字傳參
        ticket_data = f.read()
        t_data = eval(ticket_data)
        print("%s查詢剩餘票數爲%s"%(i,t_data["count"]))
def get_t(i,l1):
    # l1.acquire()#加鎖
    with l1: #用了該枷鎖方法,就不用手動解鎖了
        with open("ticket","r",encoding="utf-8")as f:
            ticket_data = f.read()  #ticket票 data數據
            t_data = eval(ticket_data)
        if t_data["count"]>0:
            t_data["count"]-=1
            print("%s搶票成功"%i)
            time.sleep(0.2)
            with open("ticket","w")as f:
                f.write(str(t_data))
        else:
            print("沒有票了")
    # l1.release()  #解鎖
if __name__ == '__main__':
    l1 = Lock()
    for i in range(10):
        p1 = Process(target=show_t,args=(i,))
        p1.start()
    for i in range(10):
        p2=Process(target=get_t,args=(i,l1)) #傳兩個參數要加括號
        p2.start()

7、關於multiprocessing包的Queue模塊的使用

 

方法介紹:
obj.put()  #往隊列裏面放數據,若是隊列裏面滿了,會阻塞
obj.put_nowait() #滿了就報錯(不會阻塞程序,能夠經過捕獲異常來進行其餘的操做)
obj.get()   #從隊列裏面取數據,若是隊列裏面空了,會阻塞(等待)
obj.get_nowait()    #空了就報錯(不會阻塞程序,能夠經過捕獲異常來進行其餘的操做)
obj.full()   #查看隊列是否滿了,滿了返回True,但該命令的執行速度比put和get的速度快,因此結果不許確
obj.empty()  #查看隊列是否空了,空了返回True,結果同理,有時不許確
obj.qsize()  #返回當前隊列內容的長度,結果也不許確

舉例:關於Queue

from multiprocessing import Process,Queue
def f1(q):
    q.put('約嗎?')
if __name__ == '__main__':
    q = Queue(3)
    p = Process(target=f1,args=(q,))
    p.start()  #開啓子進程
    son_p_msg = q.get()  #從隊列裏面拿數據,隊列爲空,則阻塞等待
    print('來自子進程的消息:',son_p_msg)

8、JoinableQueue方法(跟Queue相近)

JoinableQueue的實例p除了與Queue對象相同的方法以外還具備:
方法介紹: q.task_done():使用者使用此方法發出信號,表示q.get()的返回項目已經被處理。若是調用此方法的次數大於從隊列中刪除項目的數量,將引起ValueError異常         下面例子中,應用此方法目的,是爲了解決,當有多個消費者程序,去隊列裏拿數據的時候,不知道隊列裏是否空了,而此方法,會往隊列裏面放入一個信號,表示該數據被拿走了. q.join():生產者調用此方法進行阻塞,直到隊列中全部的項目均被處理。阻塞將持續到隊列中的每一個項目均調用q.task_done()方法爲止
import time
from multiprocessing import Process,Queue,JoinableQueue
#生產者
def producer(q):
    for i in range(10):
        time.sleep(0.2)
        s = '大包子%s號'%i
        print(s+'新鮮出爐,拿去用')
        q.put(s)
    q.join() #等待的是隊列的內容處理完畢(q是隊列的實例化對象),而不是等待上面代碼執行,就等着task_done()信號的數量,和我put進去的數量相同時,才繼續執行下面代碼
print('全部的任務都被處理了,繼續潛行吧騷年們')
#消費者
def consumer(q):
    while 1:
        time.sleep(0.5)
        baozi = q.get()
        print(baozi+'被吃了')
        q.task_done()  #給隊列發送一個取出的這個任務已經處理完畢的信號
if __name__ == '__main__':
    # q = Queue(30)
    q = JoinableQueue(30) #一樣是一個長度爲30的隊列
    pro_p = Process(target=producer,args=(q,))
    con_p = Process(target=consumer,args=(q,))
    pro_p.start()
    con_p.daemon = True #開啓守護進程,消費者會隨着主進程的結束而終結
    con_p.start()
    pro_p.join()  #讓主進程等待(生產者)子進程
    print('主進程結束')

 9、Manager方法

 

什麼是Manager方法:
Manager是是一種數據共享的方法.一種較爲高級的多進程通訊方式
進程之間的通訊:隊列、管道、數據共享(Manager). 
  隊列,管道,這些方式只適用於多個進程都是源於同一個父進程的狀況。若是多個進程不是源於同一個父進程,只能用共享內存,信號量等方式,還有就是數據共享(Manager) 多進程共同去處理共享數據的時候,就和咱們多進程同時去操做一個文件中的數據是同樣的,不加鎖就會出現錯誤的結果,進程不安全的,因此也須要加鎖

 

 

 

import time
from multiprocessing import Process,Manager,Lock #建立進程的方法\數據共享的方法\互斥鎖方法
def f1(m_d,l2):
    with l2:
        tmp = m_d["num"]
        tmp -= 1
        time.sleep(0.1)
        m_d["num"]=tmp
if __name__ == '__main__':
    m = Manager()  #實例化數據共享的對象
    l2 = Lock  #實例化鎖的對象
    m_d = m.dict({"num":100})
    p_list = []
    for i in range(10):
        p = Process(target=f1,args=(m_d,l2))
        p.start()
        p_list.append(p)
    [pp.join() for pp in p_list]
    print(m_d["num"])
相關文章
相關標籤/搜索