了解进程
进程是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
进程的概念主要有两点:第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(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")