瞭解進程
進程是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。在早期面向進程設計的計算機結構中,進程是程序的基本執行實體;在當代面向線程設計的計算機結構中,進程是線程的容器。程序是指令、數據及其組織形式的描述,進程是程序的實體。
進程的概念主要有兩點:第一,進程是一個實體。每一個進程都有它自己的地址空間,一般情況下,包括文本區域(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")