1. 程式人生 > >python之路--進程內容補充

python之路--進程內容補充

bubuko style 程序 __name__ 訪問 nor ont owa 占用

1. 進程的其他方法

  進程id, 進程名字, 查看進程是否活著(is_alive()), terminate()發送結束進程的信號

import time
import os
from multiprocessing import Process

def f1():
    print(‘子進程的pid‘,os.getpid())
    print(‘降龍十八掌天下第一‘)
def f2():
    print(‘六脈神劍舉世無雙‘)

if __name__ == ‘__main__‘:
    p1 = Process(target=f1,name=‘我是進程1‘)
    p2 = Process(target=f2,)
    p1.start()
    p2.start()
    print(p1.name) # 我是進程1
    print(‘子進程的pid‘,p1.pid)
    print(‘父進程的id‘,os.getpid())


def f1():
    time.sleep(3)
    print(‘子進程1號‘)

if __name__ == ‘__main__‘:
    p = Process(target=f1,)
    p.start()
    print(p.is_alive()) # True, 判斷進程是否活著
    p.terminate()  # 給系統發送一個結束進程的信號
    time.sleep(0.5)  # 為了讓避免並發導致的下面結果不準
    print(p.is_alive())  # False

2. 僵屍進程和孤兒進程(了解)

   僵屍進程可以理解為一些進程垃圾, 沒有實際作用, 但是在占用著空間, 當這些進程的父進程正常關閉的時候會清楚這些僵屍進程,

   孤兒進程也是一些進程垃圾, 只不過是當父進程非正常關閉的時候, 這些垃圾需要被最上級進程清理.

3. 驗證進程之間是空間隔離的

from multiprocessing import Process
num = 100
def f1():
    global num
    num = 3
    print(‘子進程中的num‘,num)

if __name__ == ‘__main__‘:
    p = Process(target=f1,)
    p.start()  # 子進程中的num 3
    p.join()
    print(‘主進程中的num‘,num)  # 主進程中的num 100

  技術分享圖片

4. 守護進程

import time
from multiprocessing import Process

def f1():
    time.sleep(1)
    print(‘我是沈睡1秒的子進程‘)
    time.sleep(3)
    print(‘我是沈睡3秒子進程‘) # 打印不出來
def f2():
    time.sleep(1)
    print(‘我是普通的子進程‘)

if __name__ == ‘__main__‘:
    p = Process(target=f1,)
    # 將該進程設置為守護進程,必須寫在start之前,
    # 意思如果我的主進程代碼運行結束了,你這個子進程不管運行到什麽地方,都直接結束
    p.daemon = True
    p.start()
    # 開啟一個普通的子進程來驗證一下守護進程的結束只和主進程的代碼運行結束有關系,
    # 而整個程序的結束需要主進程和普通的子進程的代碼都運行結束才結束
    p2 = Process(target=f2,)
    p2.start()
    time.sleep(2)
    print(‘====‘,‘我是主進程‘)
# f1 只能打印出我是沈睡1秒的子進程,
# 主進程打印出==== 我是主進程,然後打印出我是普通的子進程

5. 進程鎖(同步鎖/互斥鎖) (非常重要)

   進程鎖就是為了保證數據安全, 比如說搶票如果只剩一張票的話,很多人同時訪問都能看到只剩一張票,如果不用進程鎖的數據就會發生錯誤.

import time
from multiprocessing import Process,Lock
def show_ticket(i):
    with open(‘ticket‘,‘r‘,encoding=‘utf-8‘) as f:
        ticket_data = f.read() # 文件中的數據{‘count‘: 1}
    t_data = eval(ticket_data)
    print(‘%s查詢剩余票數為%s‘%(i,t_data[‘count‘]))
def get_ticket(i,l1):
    # 上鎖,所有人只能搶這一個鎖,只有搶到了才能繼續執行,避免了由於並發導致的數據不準
    l1.acquire()
    with open(‘ticket‘, ‘r‘, encoding=‘utf-8‘) as f:
        ticket_data = f.read()
        # print(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_ticket,args=(i,))
        p1.start()
    for i in range(10):
        p2 = Process(target=get_ticket,args=(i,l1) )
        p2.start()


def f1(i,lic):
    with lic:  # 直接完成了上鎖與解鎖的過程
        time.sleep(1)
        print(i)

if __name__ == ‘__main__‘:
    lic = Lock()
    for i in range(5):
        p = Process(target=f1, args=(i,lic))
        p.start()

6. 隊列

from multiprocessing import Process,Queue
q = Queue(3)
q.put(‘喬峰‘)
q.put(‘段譽‘)
q.put(‘虛竹‘)
print(q.get())
print(q.get())
print(q.get())
try:
    # 為了不等待直接執行下面的代碼 如果是q.get()程序就會在這一直等著直到再次出現q.put()
    q.get_nowait()
except:
    print(‘隊列拿空了‘)
print(‘還有東西嗎?‘)

# 基於隊列的通信
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) # 來自子進程的消息: 約不約?

7. 基於隊列的生產者消費者模型

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 是 JoinableQueue 裏面的join
    q.join() #就等著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 = 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()
    # 這個join 是 process裏面的join
    pro_p.join()
    print(‘主進程結束‘)

### 這兩個join在兩個模塊裏,功能不一樣

 

進程id,進程名字,查看進程是否活著is_alive() terminate()發送結束進程的信號

python之路--進程內容補充