python process:進程

瞭解進程

進程是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。在早期面向進程設計的計算機結構中,進程是程序的基本執行實體;在當代面向線程設計的計算機結構中,進程是線程的容器。程序是指令、數據及其組織形式的描述,進程是程序的實體。
進程的概念主要有兩點:第一,進程是一個實體。每一個進程都有它自己的地址空間,一般情況下,包括文本區域(text region)、數據區域(data region)和堆棧(stack region)。文本區域存儲處理器執行的代碼;數據區域存儲變量和進程執行期間使用的動態分配的內存;堆棧區域存儲着活動過程調用的指令和本地變量。第二,進程是一個“執行中的程序”。程序是一個沒有生命的實體,只有處理器賦予程序生命時(操作系統執行之),它才能成爲一個活動的實體,我們稱其爲進程。(來自百科)

創建一個進程

import multiprocessing
import time

def func(arg):
    pname = multiprocessing.current_process().name
    pid = multiprocessing.current_process().pid
    print("當前進程ID=%d,name=%s" % (pid, pname))
    while True:
        print(arg)
        time.sleep(1)
        pass
if __name__ == "__main__": 
    p = multiprocessing.Process(target=func, args=("hello",))
    p = multiprocessing.Process(target=func,name="勞資的隊伍",args=("hello",))
    p.daemon = True  # 設爲【守護進程】(隨主進程的結束而結束)
    p.start()
    while True:
        print("子進程是否活着?", p.is_alive())
        time.sleep(1)
        pass

進程,線程通過event通信

import multiprocessing
import threading
import time

data = 0
def sendEvent(event):
    global data
    for i in range(5):
        data += 1
        event.set()
        print("事件已發送*", data)
        time.sleep(1)
    pass
def handleEvent(event):
    global data
    for i in range(5):
        data += 1
        event.wait()
        print("事件已處理*", data)
        event.clear()
    pass

if __name__ == "__main__":
    #進程通信
    # event = multiprocessing.Event()
    # p1 = multiprocessing.Process(target=sendEvent, args=(event,))
    # p2 = multiprocessing.Process(target=handleEvent, args=(event,))
    # p1.start()
    # p2.start()
    # p2.join()
    
	#線程通信
    event = threading.Event()
    threading.Thread(target=sendEvent,args=(event,)).start()
    threading.Thread(target=handleEvent,args=(event,)).start()

    print("data=", data)

用線程來執行,結果如下:
在這裏插入圖片描述
用進程來執行,結果如下:
在這裏插入圖片描述

使用Semaphore控制進程的最大併發

import multiprocessing
import time

def func(sem):
    with sem:
        print("%s開始執行..." % (multiprocessing.current_process().name))
        time.sleep(3)
        print("%sdone!" % (multiprocessing.current_process().name))

if __name__ == "__main__":
    #控制進程數爲3
    sem = multiprocessing.Semaphore(3)
    for i in range(7):
        multiprocessing.Process(target=func, name="勞資的隊伍-%d" % (i), args=(sem,)).start()

執行結果:
在這裏插入圖片描述
共七條數據,執行過程如下:
勞資的隊伍-N 開始執行三條任務
------------ 等待3 秒 -----------------
返回三條結果,再次執行三條任務
------------ 等待3 秒 -----------------
返回三條結果,再次執行一條
------------ 等待3 秒 -----------------
返回一條結果,執行完畢

通過繼承process類實現自定義進程

'''
通過繼承Process實現自定義進程
'''
import multiprocessing
import os

import time


# 通過繼承於Process實現自定義進程
class MyProcess(multiprocessing.Process):
    def __init__(self, name):
        super().__init__()
        self.name = name

    def run(self):
        pid = os.getpid()
        ppid = os.getppid()
        pname = multiprocessing.current_process().name
        #pname當前活動進程名,pid當前活動進程id,ppid主進程id
        print("勞資名叫%s,ID是%d,我爸ID是%d" % (pname, pid, ppid))  
        time.sleep(5)
        print("-----勞資卒於%s-----" % (time.ctime()))
        
if __name__ == "__main__":
    MyProcess("戰狼中隊冷鋒").start()
    MyProcess("戰狼中隊熱風").start()
    MyProcess("戰狼中隊暴風").start()

    print("主進程ID是", multiprocessing.current_process().pid)
    # 獲取CPU核數
    coreCount = multiprocessing.cpu_count()
    print("勞資的CPU是%d核的" % (coreCount))
    
    # 獲得當前活動進程列表
    plist = multiprocessing.active_children()
    for p in plist:
        print(p.name)

執行結果如下:
在這裏插入圖片描述
進程間數值共享

'''
在進程間共享數值
'''
import multiprocessing
import threading

import time

# data = multiprocessing.Value("i",0)

# 在進程間共享一個數值
pValue = multiprocessing.Value("d", 0)

# 在進程間共享一組數值
pArray = multiprocessing.Array("i", [0, 1, 2, 3, 4])


def sendEvent(event, pValue, pArray):
    for i in range(5):
        pValue.value += 1.5
        pArray[0] = 99999

        event.set()
        print("事件已發送*", pValue.value)
        time.sleep(1)
    pass

def handleEvent(event, pValue, pArray):
    for i in range(5):
        event.wait()
        print("事件已處理*", pValue.value, pArray[0])
        event.clear()
    pass


if __name__ == "__main__":
    event = multiprocessing.Event()
    p1 = multiprocessing.Process(target=sendEvent, args=(event, pValue, pArray))
    p2 = multiprocessing.Process(target=handleEvent, args=(event, pValue, pArray))
    p1.start()
    p2.start()
    p2.join()

    print("data=", pValue)
    # print("main over")

'''
共享列表和字典
'''
import multiprocessing


# 編輯共享的列表和字典(以傳參形式讓進程持有數據對象(的地址))
def writeData(plist, pdict, event):
    plist += ["Python", "Java"]
    plist.append("C++")
    pdict["name"] = "冷鋒"
    event.set()
    print("event set")
    pass


# 讀取共享數據(以傳參形式讓進程持有數據對象(的地址))
def readData(plist, pdict, event):
    event.wait()
    print("event got")
    print(plist)
    print(pdict)
    event.clear()
    pass


if __name__ == "__main__":
    event = multiprocessing.Event()

    # 共享字典和列表的前提:業務完成以前,【生產字典和列表的multiprocessing.Manager對象】不能釋放
    with multiprocessing.Manager() as pm:
        # 創建可以被進程共享的列表和字典對象(不是普通的列表和字典)
        plist = pm.list()
        pdict = pm.dict()
        print(type(plist))

        # 不要重新賦值,以免改變對象類型
        # plist = []
        # pdict = {}
        # print(type(plist))

        # 讓讀寫雙方進程持有共享的數據對象
        wp = multiprocessing.Process(target=writeData, args=(plist, pdict, event))
        rp = multiprocessing.Process(target=readData, args=(plist, pdict, event))

        wp.start()
        rp.start()

        # 阻塞主線程以免pm對象被釋放
        wp.join()
        rp.join()

    # print("main over")

'''
進程間共享隊列(先進先出)
'''
import multiprocessing

# 編輯共享的列表和字典(以傳參形式讓進程持有數據對象(的地址))
from queue import Empty, Full

import time


def writeData(queue, event):
    for i in range(10):
        try:

            # 向隊列中放入元素,不寫block和timeout時,默認阻塞到能放進去爲止
            # 當前邏輯:等待1秒後強行放入,此處有可能拋出Full異常(列表已滿放你妹)
            queue.put("hello-%d" % (i), block=False, timeout=1)
            event.set()
            print("hello-%d 已放入" % (i))
            time.sleep(1)

        # 捕獲和處理放你妹異常
        except Full:
            print("該死的列表已滿")
            pass
    pass


# 讀取共享數據(以傳參形式讓進程持有數據對象(的地址))
def readData(queue, event):
    for i in range(10):
        event.wait()
        try:
            # print("event got")
            # print(queue.get(),"end")

            # 從隊列中向外拿取元素,timeout不給時,默認爲一直阻塞到能拿到元素爲止
            # 當前邏輯:等待1秒後,強行拿取,此處容易拋出Empty異常(都沒東西拿你妹)
            print(queue.get(timeout=1), "end")
            time.sleep(2)

        # 捕獲和處理拿你妹異常
        except Empty:
            print("該死的列表已空!")
            pass

    pass


if __name__ == "__main__":
    event = multiprocessing.Event()

    # 創建一個最大容量爲5的隊列(不給maxsize默認無窮大)
    pqueue = multiprocessing.Queue(maxsize=5)
    # pqueue.put(1)
    # pqueue.get()

    multiprocessing.Process(target=writeData, args=(pqueue, event)).start()
    multiprocessing.Process(target=readData, args=(pqueue, event)).start()
    print("main over")

'''
進程池示例
'''
import multiprocessing
import random

import time


def func(arg, name):
    print("正在執行{0}...".format(arg))
    time.sleep(random.randint(1, 5))
    print("進程%d完畢!" % (name))

    return "fuck"
    pass


def func2(arg, name):
    print("正在執行任務2{0}...".format(arg))
    time.sleep(random.randint(1, 5))
    print("進程%d完畢!" % (name))

    return "fuck"
    pass


# 結束回調函數
def onFuncReturn(result):
    print("得到結果{0}".format(result))
    pass


# 異步進程池示例
def asyncPoolDemo():
    # 創建一個3併發的進程池
    pool = multiprocessing.Pool(3)
    # 添加5條異步進程,執行函數各不相同,有統一的結束回調
    pool.apply_async(func=func, args=("hello", 1), callback=onFuncReturn)
    pool.apply_async(func=func2, args=("阿西吧", 2), callback=onFuncReturn)
    pool.apply_async(func=func, args=("fuck off", 3), callback=onFuncReturn)
    pool.apply_async(func=func2, args=("bye", 4), callback=onFuncReturn)
    pool.apply_async(func=func, args=("雅蠛蝶", 5), callback=onFuncReturn)
    # 關閉進程池,不再接收新的進程
    pool.close()
    # 開始所有任務,令主進程阻塞等待池中所有進程執行完畢
    pool.join()


# 同步進程池示例
def syncPoolDemo():
    # 創建一個3併發的進程池
    pool = multiprocessing.Pool(3)

    # 添加5條同步進程,執行函數各不相同
    pool.apply(func=func, args=("hello", 1))
    pool.apply(func=func2, args=("阿西吧", 2))
    pool.apply(func=func, args=("fuck off", 3))
    pool.apply(func=func2, args=("bye", 4))
    pool.apply(func=func, args=("雅蠛蝶", 5))

    # 關閉進程池,不再接收新的進程
    pool.close()
    # 開始所有任務,令主進程阻塞等待池中所有進程執行完畢
    pool.join()


if __name__ == "__main__":
    # asyncPoolDemo()
    syncPoolDemo()

    print("main over")

'''
about what
'''

# 異步進程池示例
import multiprocessing
import random

import time


def func(arg, name):
    print("正在執行{0}...".format(arg))
    time.sleep(random.randint(1, 5))
    print("進程%d完畢!" % (name))

    return random.sample(["fuck", "阿西吧", "雅蠛蝶", "你妹"], 1)
    pass


# 結束回調函數
def onFuncReturn(result):
    print("得到結果{0}".format(result))
    pass


def getPoolResultAsync():
    # 創建一個3併發的進程池
    pool = multiprocessing.Pool(3)

    # 添加5條異步進程,執行函數各不相同,有統一的結束回調
    reslist = []
    for i in range(5):
        # 立刻返回一個結果的包裝器(包裝器內暫時還沒有func的真正返回值)
        res = pool.apply_async(func=func, args=("hello", i), callback=onFuncReturn)
        print("立刻打印結果:", res)  # <multiprocessing.pool.ApplyResult object at 0x000001FA4FB70908>

        # 收集結果(的包裝器)
        reslist.append(res)

    # 關閉進程池,不再接收新的進程
    pool.close()
    # 開始所有任務,令主進程阻塞等待池中所有進程執行完畢
    pool.join()

    # 打印結果(包裝器內已有進程函數的執行結果)
    for res in reslist:
        print(res.get())  # 從結果包裝器中拿到返回值並打印


def getPoolResultSync():
    # 創建一個3併發的進程池
    pool = multiprocessing.Pool(3)

    # 添加5條異步進程,執行函數各不相同,有統一的結束回調
    reslist = []
    for i in range(5):
        # 直接獲得返回值【異步結果.get()】【源碼:return self.apply_async(func, args, kwds).get()——異步變同步!】
        res = pool.apply(func=func, args=("hello", i))

        # 收集結果
        reslist.append(res)

    # 關閉進程池,不再接收新的進程
    pool.close()
    # 開始所有任務,令主進程阻塞等待池中所有進程執行完畢
    pool.join()

    # 打印結果
    for res in reslist:
        print(res)


if __name__ == "__main__":
    getPoolResultAsync()
    # getPoolResultSync()
    print("main over")

'''
進程池示例
'''
import multiprocessing
import random

import time


def func(arg, name):
    print("正在執行{0}...".format(arg))
    time.sleep(random.randint(1, 5))
    print("進程%d完畢!" % (name))

    return "fuck"
    pass


def func2(arg, name):
    print("正在執行任務2{0}...".format(arg))
    time.sleep(random.randint(1, 5))
    print("進程%d完畢!" % (name))

    return "fuck"


# 結束回調函數
def onFuncReturn(result):
    print("得到結果{0}".format(result))
    pass


# 異步進程池示例
def asyncPoolDemo():
    # 待併發執行的函數列表
    funclist = [func, func2, func, func2, func]

    # 創建一個3併發的進程池
    pool = multiprocessing.Pool(3)

    # 遍歷函數列表,將每一個函數丟入進程池中
    for i in range(len(funclist)):
        pool.apply_async(func=funclist[i], args=("hello", i), callback=onFuncReturn)

    # 關閉進程池,不再接收新的進程
    pool.close()
    # 開始所有任務,令主進程阻塞等待池中所有進程執行完畢
    pool.join()


if __name__ == "__main__":
    asyncPoolDemo()

    print("main over")

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章