進程與多進程_易理解

多進程_篇

什麼是一個進程

進程是一個已運行程序的實例python

程序與進程的區別

程序是一個死的,進程是一個程序運行在內存中windows

當建立進程時,子進程是徹底複製的父進程(主進程)的app

原理; 實例 (不能在Windows上運行)

實例:

# 多進程
# 實現同時執行多個方法
import os

# 任務一   跳舞
import time


def dance():
    # 輸出屢次
    for i in range(3):
        print('我在跳舞!')
        time.sleep(1)


# 任務二   唱歌
def sing():
    # 輸出屢次
    for i in range(3):
        print('我在唱歌')
        time.sleep(1)


# 建立多進程
stat = os.fork()
# 判斷誰是主進程與子進程   主進程ID大於0
if stat == 0:
    # 調用子進程
    dance()
else:
    # 調用主進程
    sing()

屢次fork

# coding=utf-8
import os
import time

# 注意,fork函數,只在Unix/Linux/Mac上運行,windows不能夠
pid = os.fork()
if pid == 0:
    print('hello 1')
else:
    print('hello 2')

pid = os.fork()
if pid == 0:
    print('hello 3')
else:
    print('hello 4')

time.sleep(1)

使用類建立多進程 (推薦) 可跨平臺運行

須要使用模塊 processdom

實例

import os
import time
from multiprocessing import Process


# 使用類建立一個多進程

def sing():
    # 查看進程id
    print(f'個人進程id是:{os.getpid()}')
    print(f'父進程id是:{os.getppid()}')
    for i in range(3):
        print('我在唱歌')
        time.sleep(1)


def dance():
    # 查看進程id
    print(f'個人進程id是:{os.getpid()}')
    print(f'父進程id是:{os.getppid()}')
    for i in range(3):
        print('我在跳舞')
        time.sleep(1)


# 建立調試方法    (規範)
def main():
    #  建立一個進程對象
    p1 = Process(target=sing)  # 注意: 這裏調用方法是不能加括號的
    # 開啓進程
    p1.start()

    # 建立一個子進程
    p2 = Process(target=dance)
    # 開啓進程
    p2.start()


if __name__ == '__main__':
    main()

運行結果:異步

運行結果

建立了兩個子進程,一個主進程async

進程類參數的傳遞(Process)

實例:

import time
from multiprocessing import Process

# 參數傳遞規範   延遲:sleep       循環數:cycle

# 練習參數傳遞
def sing(sleep, cycle,**kwargs):
    for i in range(cycle):
        print('我在唱歌')
        print(kwargs)		# 打印關鍵字傳參
        time.sleep(sleep)

def dance(sleep, cycle):
    for i in range(cycle):
        print('我在跳舞')
        time.sleep(sleep)

def main():
    # 初始化時間
    time_start = time.time()
    # 建立多進程
    p1 = Process(target=sing, args=(1, 3),kwargs={"kw":'sing'})
    # 開啓進程
    p1.start()
    # 建立子進程
    p2 = Process(target=dance, args=(1, 3))
    # 開啓進程
    p2.start()

#     等待子進程結束才執行
    p1.join()
    #  當p1結束時再執行後面的
    p2.join()
    print(f'運行時間:{time.time()-time_start}')		# 計算運行時間

#     無論子進程是否運行結束,直接終止子進程
    p1.terminate()
    p2.terminate()

#         在Windows下開發 必須放在main 裏面,否則會報錯
if __name__ == '__main__':
    main()

當子進程被主進程幹掉的時候纔會被回收銷燬函數

進程池

什麼是進程池?

​ 進程池就是設定幾個進程作任務,誰先幹完,誰繼續換活幹。調試

​ 例如: 公園裏的小船,已知的船數量,不一樣的人去坐,誰先下船,就換人上船code

實例:

# 進程池
import os
from multiprocessing import Pool
import time, random


def pool(i):
    print('PID: {}  運行:{}'.format(os.getpid(),i))
    # 隨機時間
    time.sleep(random.random() * 2)

p = Pool(3)  # 設置進程池有三個進程
for i in range(10):
    # 調用異步,分配任務
    p.apply_async(pool,(i,))

p.close()       # 不能在添加任務
p.join()        # 等待全部子進程運行結束
print('運行結束')

進程池是解決每個任務建立一個進程佔用內存空間大的問題orm

進程間通訊( 經過隊列來實現 )

使用模塊:from multiprocessing import Queue

實例:

from multiprocessing import Queue, Process

#  實例   邊寫邊讀

# 讀
def read(queue):
    while True:
        # 讀取一個
        if not queue.empty():
            print(queue.get())
        else:
            #  退出
            break

# 寫
def write(queue):
    for i in ['a', 'b', 'c', 'd']:
        # 添加進隊列
        queue.put(i)

def main():
    # 建立一個隊列
    queue = Queue()
    #         建立一個對象
    p = Process(target=write, args=(queue,))  # 元組傳入
    #     啓動進程
    p.start()
    # 建立一個對象
    p1 = Process(target=read, args=(queue,))  # 元組傳入
    # 開啓進程
    p1.start()

補充:

什麼是一個殭屍進程:

​ 當子進程死的時候,主進程還在睡,遲遲沒有進行對子進程的回收;子進程並無退出,仍然佔用着系統的資源

​ 解決方法,殺死主進程,子進程由1號進程接管

什麼是孤兒進程:

​ 當主進程掛掉的時候,子進程還沒運行完,此時全部的子進程由1號進程接管,當1號進程接管時,子進程將變爲守護進程.

什麼是守護進程:

​ 守護進程一班用於服務;一直運行直到系統關閉,只有在任務完成後自動結束

相關文章
相關標籤/搜索