进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
在python中要想使用进程,需要导入multiprocessing模块。
1.进程的基本实现:
import multiprocessing
import time
def run(num):
i = 0
while i < num :
print("小明跑步,跑了%d圈" % i)
time.sleep(1)
i += 1
def listen(num):
i = 0
while i < num:
print("小明听歌,听第%d首歌" % i)
time.sleep(1)
i += 1
def main():
#进程1、进程2创建的准备工作,arge后面传的是元组
p1 = multiprocessing.Process(target=run, args=(10,))
p2 = multiprocessing.Process(target=listen, args=(10,) )
#开始进程1和进程2,进程的生命周期是从开始的时候被创建到函数结束死亡
p1.start()
p2.start()
if __name__ == '__main__':
main()
运行结果:
小明跑步,跑了0圈
小明听歌,听第0首歌
小明跑步,跑了1圈
小明听歌,听第1首歌
小明跑步,跑了2圈
小明听歌,听第2首歌
小明跑步,跑了3圈
小明听歌,听第3首歌
小明跑步,跑了4圈
小明听歌,听第4首歌
小明跑步,跑了5圈
小明听歌,听第5首歌
小明跑步,跑了6圈
小明听歌,听第6首歌
小明跑步,跑了7圈
小明听歌,听第7首歌
小明听歌,听第8首歌
小明跑步,跑了8圈
小明听歌,听第9首歌
小明跑步,跑了9圈
注意:子进程会拷贝主进程的所有代码,然后执行。
2.进程池 Pool:
Pool可以提供指定数量的进程供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它。
我的理解是,银行有5个窗口,有好多人要来办事情,第一次可以去五个人,后面的人就是哪里有空了去哪里,以次类推。
实现:
import random
import os
from multiprocessing import Pool
import time
def demo(name):
print("%s开始进行,进程号是%s"%(name, os.getpid()))
#记录进程开始的时间
t_start = time.time()
#让进程随机睡以小段时间
time.sleep(random.random()*2)
#进录进程结束的时间
t_end = time.time()
print("我是进程%s,我来了,我进行的时间是%.2f,我走了" % (name, (t_end-t_start)))
def main():
#创建一个进程池,最大进程数是3
my_pool = Pool(3)
for i in range(10):
my_pool.apply_async(demo,(i,))
my_pool.close()
#这里主进程必须等待子进程全部结束
my_pool.join()
if __name__ == '__main__':
main()
运行结果:
0开始进行,进程号是7375
1开始进行,进程号是7376
2开始进行,进程号是7377
我是进程0,我来了,我进行的时间是0.19,我走了
3开始进行,进程号是7375
我是进程1,我来了,我进行的时间是1.17,我走了
4开始进行,进程号是7376
我是进程3,我来了,我进行的时间是1.13,我走了
5开始进行,进程号是7375
我是进程2,我来了,我进行的时间是1.45,我走了
6开始进行,进程号是7377
我是进程6,我来了,我进行的时间是0.54,我走了
7开始进行,进程号是7377
我是进程4,我来了,我进行的时间是1.07,我走了
8开始进行,进程号是7376
我是进程8,我来了,我进行的时间是0.56,我走了
9开始进行,进程号是7376
我是进程9,我来了,我进行的时间是0.09,我走了
我是进程5,我来了,我进行的时间是1.68,我走了
我是进程7,我来了,我进行的时间是1.96,我走了
由结果可以看出进程池是提供指定数量的进程供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它。