进程:操作系统提供的抽象概念,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。程序是指令、数据及其组织形式的描述,进程是程序的实体。程序本身是没有生命周期的,它只是存在磁盘上的一些指令,程序一旦运行就是进程。
在python中,利用multiprocessing可以实现多进程。multiprocessing是一个支持使用与 threading 模块类似的 API 来产生进程的包。 multiprocessing 包同时提供了本地和远程并发操作,通过使用子进程而非线程有效地绕过了 全局解释器锁。 因此,multiprocessing 模块允许程序员充分利用给定机器上的多个处理器。 它在 Unix 和 Windows 上均可运行。
在 multiprocessing 中,通过创建一个 Process 对象然后调用它的 start() 方法来生成进程。需要说明的以下几个方法的区别:
run():表示进程活动的方法。调用此方法仅仅执行方法,并不会产生进程;
start():启动进程活动。这个方法每个进程对象最多只能调用一次。它会将对象的 run() 方法安排在一个单独的进程中调用。
join([timeout])如果可选参数 timeout 是 None (默认值),则该方法将阻塞,直到调用 join() 方法的进程终止。如果 timeout 是一个正数,它最多会阻塞 timeout 秒。请注意,如果进程终止或方法超时,则该方法返回 None 。检查进程的 exitcode 以确定它是否终止。一个进程可以被 join 多次。进程无法join自身,因为这会导致死锁。尝试在启动进程之前join进程是错误的。
'''
对象调用方法:
process.start() 启动进程并执行任务
process.run() 只是执行了任务但是没有启动进程
terminate() 终止进程
'''
import os
from multiprocessing import Process
from time import sleep
def test(s):
while True:
sleep(s)
print("任务一",)
def test1(s):
while True:
sleep(s)
print("任务二",)
number = 1
if __name__ == '__main__':
#子进程
p = Process(target=test,name='renwu1',args=(1,))
p.start()
print(p.name)
p1 = Process(target=test1,name='renwu2',args=(2,))
p1.start()
print(p1.name)
while True:
number +=1
sleep(0.2)
if number ==50:
p.terminate()
p1.terminate()
break
else:
print("--------")
使用全局:
''' 进程与线程的对比: 进程:完成多个任务,一个电脑同时运行多个程序 线程:完成多个任务 一个程序当中进行多个案例 一个程序 至少一个进程 一个进程至少有一个线程 ''' #全局 from multiprocessing import Process from time import sleep m = 1 def test(s): global m while True: sleep(s) m+=1 print("任务一",m) def test1(s): global m while True: sleep(s) m+=1 print("任务二",m) number = 1 if __name__ == '__main__': #子进程 p = Process(target=test,name='renwu1',args=(1,)) p.start() p1 = Process(target=test1,name='renwu2',args=(2,)) p1.start() while True: sleep(1) m+=1 print("=====",m)
自定义进程:
from multiprocessing import Process
class Myprocess(Process):
def __init__(self, name):
super(Myprocess, self).__init__()
self.name = name
#重写run方法
def run(self):
n = 1
while True:
print("{}----自定义进程,n:{}".format(self.name,n))
n += 1
if __name__ == '__main__':
p = Myprocess('xioaming')
p.start()
p1 =Myprocess('ki')
p1.start()
进程之阻塞式:
'''
阻塞式 特点:添加一个执行一个任务,如果任务不能结束,另一个也不会开始
'''
import time
import os
from multiprocessing import Pool
from random import random
#任务
def tesk(tesk_name):
print('开始做任务',tesk_name)
start = time.time()
time.sleep(random()*2)#随机数
end = time.time()
print("完成任务:{},用时{}:,id号为:{}".format(tesk_name,end-start,os.getpid()))
if __name__ == '__main__':
#进程池最大任务量为5
Pool = Pool(5)
tesks =['吃饭','睡觉','学习','玩游戏','旅游','聚会','逛']
for tesk1 in tesks:
#apply_async 异步
Pool.apply(tesk,args=(tesk1,))
# 添加任务结束
Pool.close()
# 类似于一堵墙,将大于进程池的堵在门外
# 当进程池任务结束后再进行其他任务
Pool.join() #让主进程让步
print('结束')
开始做任务 吃饭
完成任务:吃饭,用时1.4228670597076416:,id号为:16392
开始做任务 睡觉
完成任务:睡觉,用时1.9225292205810547:,id号为:17488
开始做任务 学习
完成任务:学习,用时0.04509282112121582:,id号为:11752
开始做任务 玩游戏
完成任务:玩游戏,用时0.7141571044921875:,id号为:856
开始做任务 旅游
完成任务:旅游,用时1.2428359985351562:,id号为:1480
开始做任务 聚会
完成任务:聚会,用时1.4147367477416992:,id号为:16392
开始做任务 逛
完成任务:逛,用时0.8820264339447021:,id号为:17488
结束
非阻塞式:
'''
阻塞式:
非阻塞式:进程池可以复用 全部添加到队列中,立刻返回
并没有等待其他的进程完毕,但是回调函数,等待任务完成后再调用
'''
#非阻塞式
import time
import os
from multiprocessing import Pool
from random import random
#任务
def tesk(tesk_name):
print('开始做任务',tesk_name)
start = time.time()
time.sleep(random()*2)#随机数
end = time.time()
return "完成任务:{},用时{}:,id号为:{}".format(tesk_name,end-start,os.getpid())
#回调函数
container = []
def callback_func(n):
container.append(n)
if __name__ == '__main__':
#进程池最大任务量为5
Pool = Pool(5)
tesks =['吃饭','睡觉','学习','玩游戏','旅游','聚会','逛']
for tesk1 in tesks:
#apply_async 异步
Pool.apply_async(tesk,args=(tesk1,),callback=callback_func) #callback回调
# 添加任务结束
Pool.close()
# 类似于一堵墙,将大于进程池的堵在门外
# 当进程池任务结束后再进行其他任务
Pool.join()
for c in container:
print(c)
print('结束')
开始做任务 吃饭
开始做任务 睡觉
开始做任务 学习
开始做任务 玩游戏
开始做任务 旅游
开始做任务 聚会
开始做任务 逛
完成任务:睡觉,用时0.3931703567504883:,id号为:17268
完成任务:旅游,用时0.4772605895996094:,id号为:16660
完成任务:玩游戏,用时0.506080150604248:,id号为:15944
完成任务:学习,用时0.5301523208618164:,id号为:196
完成任务:聚会,用时0.7048521041870117:,id号为:17268
完成任务:吃饭,用时1.229477882385254:,id号为:14472
完成任务:逛,用时1.0550172328948975:,id号为:16660
结束
进程间的通信:
'''
进程间通信:进程之间使用一个队列来完成通信
'''
from multiprocessing import Queue,Process
from time import sleep
import time
def download(q):
images = ['a.jpg','b.jpg','c.jpg']
for image in images:
print("正在下载:",image)
sleep(0.5)
q.put(image)
def getfile(q):
while True:
try:
file = q.get(timeout=5)
print("{}保存成功".format(file))
except:
print("保存成功")
break
if __name__ == '__main__':
q = Queue(5)
p = Process(target=download,args=(q,))
p2 = Process(target=getfile,args=(q,))
p.start()
p.join()
p2.start()
p2.join()
print('-----')
C:\Users\lenovo\PycharmProjects3\venv\Scripts\python.exe C:/Users/lenovo/PycharmProjects3/python学习/python基础学习/day7-进程间的通信.py
正在下载: a.jpg
正在下载: b.jpg
正在下载: c.jpg
a.jpg保存成功
b.jpg保存成功
c.jpg保存成功
保存成功