环境:win7+python2.7

一直想学习多进程或多线程,但之前只是单纯看一点基础知识还有简单的介绍,无法理解怎么去应用,直到前段时间看了github的一个爬虫项目涉及到多进程,多线程相关内容,一边看一边百度相关知识点,现在把一些相关知识点和一些应用写下来做个记录.
首先说下什么是进程:进程是程序在计算机上的一次执行活动,当运行一个程序的时候,就启动了一个进程.而进程又分为系统进程和用户进程.只要是用于完成操作系统的各种功能的进程就是系统进程,它们就是处于运行状态下的操作系统本身;而所有由你启动的进程都是用户进程。进程是操作系统进行资源分配的单位。
直观点说,在任务管理器的用户名上标明system的是系统进程,标明administrator的是用户进程,另外net是网洛,lcacal service是本地服务,关于进程更加具体的信息可以百科,这里得省点力气,不然收不回了.
一.多进程的简单使用
如图,multiprocessing有多个函数,很多我也还没去了解,这里只讲我目前了解的.
进程创建:Process(target=主要运行的函数,name=自定义进程名称可不写,args=(参数))
方法:
其中,Process以start()启动某个进程。
属性:
1.Process(),start(),join()
# -*- coding:utf-8 -*- from multiprocessing import Process import time def fun1(t): print 'this is fun1',time.ctime() time.sleep(t) print 'fun1 finish',time.ctime() def fun2(t): print 'this is fun2',time.ctime() time.sleep(t) print 'fun2 finish',time.ctime() if __name__ == '__main__': a=time.time() p1=Process(target=fun1,args=(4,)) p2 = Process(target=fun2, args=(6,)) p1.start() p2.start() p1.join() p2.join() b=time.time() print 'finish',b-a
这里一共开了两个进程,p1和p2,arg=(4,)中的4是fun1函数的参数,这里要用tulpe类型,如果两个参数或更多就是arg=(参数1,参数2...),之后用start()启动进程,我们设置等待p1和p2进程结束再执行下一步.来看下面的运行结果,fun2和fun1基本在同一时间开始运行,当运行完毕(fun1睡眠4秒,同时fun2睡眠6秒),才执行print 'finish',b-a语句
this is fun2 Mon Jun 05 13:48:04 2017 this is fun1 Mon Jun 05 13:48:04 2017 fun1 finish Mon Jun 05 13:48:08 2017 fun2 finish Mon Jun 05 13:48:10 2017 finish 6.20300006866 Process finished with exit code 0
我们再来看下start()与join()处于不同位置会发生什么
# -*- coding:utf-8 -*- from multiprocessing import Process import time def fun1(t): print 'this is fun1',time.ctime() time.sleep(t) print 'fun1 finish',time.ctime() def fun2(t): print 'this is fun2',time.ctime() time.sleep(t) print 'fun2 finish',time.ctime() if __name__ == '__main__': a=time.time() p1=Process(target=fun1,args=(4,)) p2 = Process(target=fun2, args=(6,)) p1.start() p1.join() p2.start() p2.join() b=time.time() print 'finish',b-a
结果:
this is fun1 Mon Jun 05 14:19:28 2017 fun1 finish Mon Jun 05 14:19:32 2017 this is fun2 Mon Jun 05 14:19:32 2017 fun2 finish Mon Jun 05 14:19:38 2017 finish 10.1229999065 Process finished with exit code 0
看,现在是先运行fun1函数,运行完毕再运行fun2接着再是print 'finish',即先运行进程p1再运行进程p2,感受到join()的魅力了吧.现在再试试注释掉join()看看又会出现什么
# -*- coding:utf-8 -*- from multiprocessing import Process import time def fun1(t): print 'this is fun1',time.ctime() time.sleep(t) print 'fun1 finish',time.ctime() def fun2(t): print 'this is fun2',time.ctime() time.sleep(t) print 'fun2 finish',time.ctime() if __name__ == '__main__': a=time.time() p1=Process(target=fun1,args=(4,)) p2 = Process(target=fun2, args=(6,)) p1.start() p2.start() p1.join() #p2.join() b=time.time() print 'finish',b-a
结果:
this is fun1 Mon Jun 05 14:23:57 2017 this is fun2 Mon Jun 05 14:23:58 2017 fun1 finish Mon Jun 05 14:24:01 2017 finish 4.05900001526 fun2 finish Mon Jun 05 14:24:04 2017 Process finished with exit code 0
这次是运行完fun1(因为p1进程有用join(),所以主程序等待p1运行完接着执行下一步),接着继续运行主进程的print 'finish',最后fun2运行完毕才结束
2.name,daemon,is_alive():
# -*- coding:utf-8 -*- from multiprocessing import Process import time def fun1(t): print 'this is fun1',time.ctime() time.sleep(t) print 'fun1 finish',time.ctime() def fun2(t): print 'this is fun2',time.ctime() time.sleep(t) print 'fun2 finish',time.ctime() if __name__ == '__main__': a=time.time() p1=Process(name='fun1进程',target=fun1,args=(4,)) p2 = Process(name='fun2进程',target=fun2, args=(6,)) p1.daemon=True p2.daemon = True p1.start() p2.start() p1.join() print p1,p2 print '进程1:',p1.is_alive(),'进程2:',p2.is_alive() #p2.join() b=time.time() print 'finish',b-a
结果:
this is fun2 Mon Jun 05 14:43:49 2017 this is fun1 Mon Jun 05 14:43:49 2017 fun1 finish Mon Jun 05 14:43:53 2017 <Process(fun1进程, stopped daemon)> <Process(fun2进程, started daemon)> 进程1: False 进程2: True finish 4.06500005722 Process finished with exit code 0
可以看到,name是给进程赋予名字, 运行到print '进程1:',p1.is_alive(),'进程2:',p2.is_alive() 这句的时候,p1进程已经结束(返回False),p2进程仍然在运行(返回True),但p2没有用join(),所以直接接着执行主进程,由于用了daemon=Ture,父进程终止后自动终止,p2进程没有结束就强行结束整个程序了.
3.run()
run()在Process没有指定target函数时,默认用run()函数运行程序,
# -*- coding:utf-8 -*- from multiprocessing import Process import time def fun1(t): print 'this is fun1',time.ctime() time.sleep(t) print 'fun1 finish',time.ctime() def fun2(t): print 'this is fun2',time.ctime() time.sleep(t) print 'fun2 finish',time.ctime() if __name__ == '__main__': a = time.time() p=Process() p.start() p.join() b = time.time() print 'finish', b - a
结果:
finish 0.0840001106262
从结果看出,进程p什么也没做,为了让进程正常运行,我们酱紫写:
目标函数没有参数:
# -*- coding:utf-8 -*- from multiprocessing import Process import time def fun1(): print 'this is fun1',time.ctime() time.sleep(2) print 'fun1 finish',time.ctime() def fun2(t): print 'this is fun2',time.ctime() time.sleep(t) print 'fun2 finish',time.ctime() if __name__ == '__main__': a = time.time() p=Process() p.run=fun1 p.start() p.join() b = time.time() print 'finish', b - a
结果:
this is fun1 Mon Jun 05 16:34:41 2017 fun1 finish Mon Jun 05 16:34:43 2017 finish 2.11500000954 Process finished with exit code 0
目标函数有参数:
# -*- coding:utf-8 -*- from multiprocessing import Process import time def fun1(t): print 'this is fun1',time.ctime() time.sleep(t) print 'fun1 finish',time.ctime() def fun2(t): print 'this is fun2',time.ctime() time.sleep(t) print 'fun2 finish',time.ctime() if __name__ == '__main__': a = time.time() p=Process() p.run=fun1(2) p.start() p.join() b = time.time() print 'finish', b - a
结果:
this is fun1 Mon Jun 05 16:36:27 2017 fun1 finish Mon Jun 05 16:36:29 2017 Process Process-1: Traceback (most recent call last): File "E:\Anaconda2\lib\multiprocessing\process.py", line 258, in _bootstrap self.run() TypeError: 'NoneType' object is not callable finish 2.0529999733 Process finished with exit code 0
目标函数有参数的出现了异常,为什么呢?我现在还找不到原因,但是实践发现,当最后一个参数赋予进程运行后,没有其他参数,就会出现这个异常,有人知道的望告知.
二.进程池
对于需要使用几个甚至十几个进程时,我们使用Process还是比较方便的,但是如果要成百上千个进程,用Process显然太笨了,multiprocessing提供了Pool类,即现在要讲的进程池,能够将众多进程放在一起,设置一个运行进程上限,每次只运行设置的进程数,等有进程结束,再添加新的进程
Pool(processes =num):设置运行进程数,当一个进程运行完,会添加新的进程进去
apply_async(函数,(参数)):非阻塞,其中参数是tulpe类型,
apply(函数,(参数)):阻塞
close():关闭pool,不能再添加新的任务
terminate():结束运行的进程,不再处理未完成的任务
join():和Process介绍的作用一样, 但要在close或terminate之后使用。
1.单个进程池
# -*- coding:utf-8 -*- from multiprocessing import Pool import time def fun1(t): print 'this is fun1',time.ctime() time.sleep(t) print 'fun1 finish',time.ctime() def fun2(t): print 'this is fun2',time.ctime() time.sleep(t) print 'fun2 finish',time.ctime() if __name__ == '__main__': a=time.time() pool = Pool(processes =3) # 可以同时跑3个进程 for i in range(3,8): pool.apply_async(fun1,(i,)) pool.close() pool.join() b=time.time() print 'finish',b-a
结果:
this is fun1 Mon Jun 05 15:15:38 2017 this is fun1 Mon Jun 05 15:15:38 2017 this is fun1 Mon Jun 05 15:15:38 2017 fun1 finish Mon Jun 05 15:15:41 2017 this is fun1 Mon Jun 05 15:15:41 2017 fun1 finish Mon Jun 05 15:15:42 2017 this is fun1 Mon Jun 05 15:15:42 2017 fun1 finish Mon Jun 05 15:15:43 2017 fun1 finish Mon Jun 05 15:15:47 2017 fun1 finish Mon Jun 05 15:15:49 2017 finish 11.1370000839 Process finished with exit code 0
从上面的结果可以看到,设置了3个运行进程上限,15:15:38这个时间同时开始三个进程,当第一个进程结束时(参数为3秒那个进程),会添加新的进程,如此循环,直至进程池运行完再执行主进程语句b=time.time() print 'finish',b-a .这里用到非阻塞apply_async(),再来对比下阻塞apply()
# -*- coding:utf-8 -*- from multiprocessing import Pool import time def fun1(t): print 'this is fun1',time.ctime() time.sleep(t) print 'fun1 finish',time.ctime() def fun2(t): print 'this is fun2',time.ctime() time.sleep(t) print 'fun2 finish',time.ctime() if __name__ == '__main__': a=time.time() pool = Pool(processes =3) # 可以同时跑3个进程 for i in range(3,8): pool.apply(fun1,(i,)) pool.close() pool.join() b=time.time() print 'finish',b-a
结果:
this is fun1 Mon Jun 05 15:59:26 2017 fun1 finish Mon Jun 05 15:59:29 2017 this is fun1 Mon Jun 05 15:59:29 2017 fun1 finish Mon Jun 05 15:59:33 2017 this is fun1 Mon Jun 05 15:59:33 2017 fun1 finish Mon Jun 05 15:59:38 2017 this is fun1 Mon Jun 05 15:59:38 2017 fun1 finish Mon Jun 05 15:59:44 2017 this is fun1 Mon Jun 05 15:59:44 2017 fun1 finish Mon Jun 05 15:59:51 2017 finish 25.1610000134 Process finished with exit code 0
可以看到,阻塞是当一个进程结束后,再进行下一个进程,一般我们都用非阻塞apply_async()
2.多个进程池
上面是使用单个进程池的,对于多个进程池,我们可以用for循环,直接看代码
# -*- coding:utf-8 -*- from multiprocessing import Pool import time def fun1(t): print 'this is fun1',time.ctime() time.sleep(t) print 'fun1 finish',time.ctime() def fun2(t): print 'this is fun2',time.ctime() time.sleep(t) print 'fun2 finish',time.ctime() if __name__ == '__main__': a=time.time() pool = Pool(processes =3) # 可以同时跑3个进程 for fun in [fun1,fun2]: for i in range(3,8): pool.apply_async(fun,(i,)) pool.close() pool.join() b=time.time() print 'finish',b-a
结果:
this is fun1 Mon Jun 05 16:04:38 2017 this is fun1 Mon Jun 05 16:04:38 2017 this is fun1 Mon Jun 05 16:04:38 2017 fun1 finish Mon Jun 05 16:04:41 2017 this is fun1 Mon Jun 05 16:04:41 2017 fun1 finish Mon Jun 05 16:04:42 2017 this is fun1 Mon Jun 05 16:04:42 2017 fun1 finish Mon Jun 05 16:04:43 2017 this is fun2 Mon Jun 05 16:04:43 2017 fun2 finish Mon Jun 05 16:04:46 2017 this is fun2 Mon Jun 05 16:04:46 2017 fun1 finish Mon Jun 05 16:04:47 2017 this is fun2 Mon Jun 05 16:04:47 2017 fun1 finish Mon Jun 05 16:04:49 2017 this is fun2 Mon Jun 05 16:04:49 2017 fun2 finish Mon Jun 05 16:04:50 2017 this is fun2 Mon Jun 05 16:04:50 2017 fun2 finish Mon Jun 05 16:04:52 2017 fun2 finish Mon Jun 05 16:04:55 2017 fun2 finish Mon Jun 05 16:04:57 2017 finish 19.1670000553 Process finished with exit code 0
看到了,在fun1运行完接着运行fun2.
另外对于没有参数的情况,就直接 pool.apply_async(funtion),无需写上参数.
在学习编写程序过程,曾遇到不用if _name_ == '_main_':而直接运行程序,这样结果会出错,经查询,在Windows上要想使用进程模块,就必须把有关进程的代码写在当前.py文件的if _name_ == ‘_main_' :语句的下面,才能正常使用Windows下的进程模块。Unix/Linux下则不需要。原因有人这么说:在执行的時候,由于你写的 py 会被当成module 读进执行。所以,一定要判断自身是否为 _main_。也就是要:
if __name__ == ‘__main__' : # do something.
这里我自己还搞不清楚,期待以后能够理解
学习的过程中,还涉及了经常和进程一起运用的队列Queue和线程threading,有时间以后再写吧,希望对大家的学习有所帮助,也希望大家多多支持。
# python
# 多进程
# 进程池
# Python多进程multiprocessing、进程池用法实例分析
# python进程池实现的多进程文件夹copy器完整示例
# python多进程(加入进程池)操作常见案例
# Python多进程池 multiprocessing Pool用法示例
# Python多进程库multiprocessing中进程池Pool类的使用详解
# Python 多进程并发操作中进程池Pool的实例
# Python基于进程池实现多进程过程解析
# 多个
# 可以看到
# 的是
# 就会
# 再来
# 自定义
# 操作系统
# 都是
# 再写
# 我也
# 几个
# 看了
# 相关内容
# 第一个
# 不需要
# 成百上千
# 我现在
# 找不到
# 主程序
# 是怎么
相关文章:
如何通过服务器快速搭建网站?完整步骤解析
如何快速搭建个人网站并优化SEO?
文字头像制作网站推荐软件,醒图能自动配文字吗?
PHP正则匹配日期和时间(时间戳转换)的实例代码
小自动建站系统:AI智能生成+拖拽模板,多端适配一键搭建
建站之星ASP如何实现CMS高效搭建与安全管理?
建站主机如何选?性能与价格怎样平衡?
制作宣传网站的软件,小红书可以宣传网站吗?
建站之星多图banner生成与模板自定义指南
如何在腾讯云服务器上快速搭建个人网站?
杭州银行网站设计制作流程,杭州银行怎么开通认证方式?
表情包在线制作网站免费,表情包怎么弄?
如何将凡科建站内容保存为本地文件?
Android自定义listview布局实现上拉加载下拉刷新功能
建站之星北京办公室:智能建站系统与小程序生成方案解析
网站制作价目表怎么做,珍爱网婚介费用多少?
如何选择域名并搭建高效网站?
宝塔新建站点为何无法访问?如何排查?
常州自助建站工具推荐:低成本搭建与模板选择技巧
建站之星后台密码遗忘?如何快速找回?
营销式网站制作方案,销售哪个网站招聘效果最好?
头像制作网站在线制作软件,dw网页背景图像怎么设置?
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
整蛊网站制作软件,手机不停的收到各种网站的验证码短信,是手机病毒还是人为恶搞?有这种手机病毒吗?
香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化
已有域名和空间如何快速搭建网站?
专业商城网站制作公司有哪些,pi商城官网是哪个?
山东网站制作公司有哪些,山东大源集团官网?
高配服务器限时抢购:企业级配置与回收服务一站式优惠方案
网站专业制作公司有哪些,做一个公司网站要多少钱?
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
如何在阿里云购买域名并搭建网站?
如何在阿里云高效完成企业建站全流程?
安云自助建站系统如何快速提升SEO排名?
金*站制作公司有哪些,金华教育集团官网?
制作网站的基本流程,设计网站的软件是什么?
济南网站制作的价格,历城一职专官方网站?
昆明网站制作哪家好,昆明公租房申请网上登录入口?
网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?
怀化网站制作公司,怀化新生儿上户网上办理流程?
如何在云主机快速搭建网站站点?
教育培训网站制作流程,请问edu教育网站的域名怎么申请?
如何解决ASP生成WAP建站中文乱码问题?
c++怎么用jemalloc c++替换默认内存分配器【性能】
建站之星免费模板:自助建站系统与智能响应式一键生成
如何用景安虚拟主机手机版绑定域名建站?
如何通过西部数码建站助手快速创建专业网站?
太原网站制作公司有哪些,网约车营运证查询官网?
如何在阿里云域名上完成建站全流程?
如何在Golang中引入测试模块_Golang测试包导入与使用实践
*请认真填写需求信息,我们会在24小时内与您取得联系。