1、概述
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
多进程模式是实现多任务模式的一种,同时还有多线程、协程!
参考:百度百科—进程
2、进程创建
from multiprocessing import Process
from time import sleep
import os
m = 1 #通过m可以看出进程是独立的资源分配单位
def task1(s,name):
global m
while True:
sleep(s)
m += 1
print('这是任务1....',os.getpid(),'------------',os.getppid(),name,'m:',m)
def task2(s,name):
global m
while True:
sleep(s)
m += 1
print('这是任务2....',os.getpid(),'------------',os.getppid(),name,'m:',m)
number = 1
if __name__ == '__main__':
#子进程
#创建进程p1
p1 = Process(target=task1,name = '任务1',args = (1,'aa'))
#启动p1进程
p1.start()
print(p1.name)
#创建p2进程
p2 = Process(target=task2,name = '任务2',args =(2,'bb'))
#启动p2进程
p2.start()
print(p2.name)
while True:
number += 1
sleep(0.2)
if number == 100:
p1.terminate() #终止进程
p2.terminate()
break
else:
print('---------------->number:',number)
总结:
from multiprocessing import Process
process = Process(target = 函数,name = 进程的名字,args = (给函数传递参数))
process 对象
对象调用方法:
process.start() 启动进程并执行任务
process.run() 只是执行了任务但是没有启动进程
terminate() 终止
注: 进程创建在不同类型os系统上创建方法不一样,上述进程是在windows10系统上创建的,以下编写代码也是在windows10系统上跑的。可以参考:Python语言,Linux下进程的创建,Windows下进程的创建
3、自定义进程
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('进程名字:'+self.name)
print('-------->自定义进程,n:{}'.format(n,self.name))
n += 1
if __name__ == '__main__':
p1 = MyProcess('小明')
p1.start()
p2 = MyProcess('小红')
4、进程池
-
概念: 当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态生成多个进程,但如果是上百甚至上千目标,手动的去创建进程工作量巨大,此时就可以用到multiprocessing模块提供的Pool方法。初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中时。如果池还没有满,那么就会创建一个新的进程用来执行该请求,但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来执行。
-
非阻塞式进程池: 全部添加到就绪队列中,立刻返回,并没有等待其他的进程完毕,但回调函数是等待任务完成之后才调用。
from multiprocessing import Pool import time from random import random import os #非阻塞式进程 def task(task_name): print('开始做任务啦!',task_name) start = time.time() time.sleep(random() * 2) end = time.time() print('完成任务:{},用时:{},进程id:{}'.format(task_name,(end - start),os.getpid())) return '完成任务:{},用时:{},进程id:{}'.format(task_name,(end - start),os.getpid()) container = [] def callback_func(n): container.append(n) print(n) if __name__ == '__main__': pool = Pool(5) #跟主进程生命期一样 tasks = ['听音乐','吃饭','洗衣服','打游戏','散步','看孩子','做饭'] for task1 in tasks: pool.apply_async(task,args=(task1,),callback=callback_func) #非阻塞式,把所有队列加到就绪列表中 pool.close() #添加任务结束 pool.join() # 就是一堵墙,所有任务都结束后,就撤掉 for i in container: print(i) print('over!!!!')
-
阻塞式进程池: 添加一个执行一个任务,如果一个任务不结束另一个任务就进不来。
from multiprocessing import Pool import time from random import random import os def task(task_name): print('开始做任务啦!',task_name) start = time.time() time.sleep(random() * 2) end = time.time() print('完成任务:{},用时:{},进程id:{}'.format(task_name,(end - start),os.getpid())) # return '完成任务:{},用时:{},进程id:{}'.format(task_name,(end - start),os.getpid()) # container = [] # def callback_func(n): # container.append(n) if __name__ == '__main__': pool = Pool(5) #跟主进程生命期一样,所以为了防止主进程提前结束,才调用了pool.join tasks = ['听音乐','吃饭','洗衣服','打游戏','散步','看孩子','做饭'] for task1 in tasks: pool.apply(task,args=(task1,)) #阻塞式 pool.close() #添加任务结束 pool.join() # 就是一堵墙,所有任务都结束后,就撤掉 # for i in container: # print(i) print('over!!!!')
-
总结
pool = Pool(max) 创建进程池对象,max表示进程池中的进程数量 pool.apply() 阻塞的 pool.apply_async 非阻塞的 pool.close() 关闭池子 pool.join() 主进程让步
5、队列
from multiprocessing import Queue
from multiprocessing import Process
from time import sleep
q = Queue(5)
q.put('A')
q.put('B')
q.put('C')
q.put('D')
q.put('E')
if not q.full():
q.put('F',timeout=3) #队列满了,这里阻塞了。
else :
print('队列已满!')
#获取队列的值
for i in range(5):
print(q.get(timeout=2))
6、进程间通信
def dowmload(q):
images = ['girl.jpg','boy.jpg','man.jpg']
for image in images:
print('正在下载:',image)
sleep(0.5)
q.put(image)
def getfile(q):
while True:
try:
file = q.get()
print('{}正在上传,保存成功!'.format(file))
except:
print('全部保存完毕')
break
if __name__ == '__main__':
Q = Queue(5)
p1 = Process(target=dowmload,args=(Q,))
p2 = Process(target=getfile,args=(Q,))
p1.start()
p2.start()
p1.join()
p2.join()