processing python模式_详解python之多进程和进程池(Processing库)

环境:win7+python2.7

一直想学习多进程或多线程,但之前只是单纯看一点基础知识还有简单的介绍,无法理解怎么去应用,直到前段时间看了github的一个爬虫项目涉及到多进程,多线程相关内容,一边看一边百度相关知识点,现在把一些相关知识点和一些应用写下来做个记录.

首先说下什么是进程:进程是程序在计算机上的一次执行活动,当运行一个程序的时候,就启动了一个进程.而进程又分为系统进程和用户进程.只要是用于完成操作系统的各种功能的进程就是系统进程,它们就是处于运行状态下的操作系统本身;而所有由你启动的进程都是用户进程。进程是操作系统进行资源分配的单位。

直观点说,在任务管理器的用户名上标明system的是系统进程,标明administrator的是用户进程,另外net是网洛,lcacal service是本地服务,关于进程更加具体的信息可以百科,这里得省点力气,不然收不回了.

一.多进程的简单使用

如图,multiprocessing有多个函数,很多我也还没去了解,这里只讲我目前了解的.

201769101320828.png?201759101416

进程创建:Process(target=主要运行的函数,name=自定义进程名称可不写,args=(参数))

方法:

is_alive():判断进程是否存活

join([timeout]):子进程结束再执行下一步,timeout为超时时间,有时进程遇到阻塞,为了程序能够运行下去而设置超时时间

run():如果在创建Process对象的时候不指定target,那么就会默认执行Process的run方法

start():启动进程,区分run()

terminate():终止进程,关于终止进程没有这么简单,貌似用psutil包会更好,有机会以后了解更多再写下。

其中,Process以start()启动某个进程。

属性:

authkey: 在文档中authkey()函数找到这么一句话:Set authorization key of process设置过程的授权密钥 ,目前没找到相关应用实例,这个密钥是怎么用的呢?文章不提

daemon:父进程终止后自动终止,且自己不能产生新进程,必须在start()之前设置

exitcode:进程在运行时为None、如果为–N,表示被信号N结束

name:进程的名字,自定义

pid:每个进程有唯一的PID编号。

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

进程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,有时间以后再写吧,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/486508.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不确定性的价值

来源: 混沌巡洋舰推荐一篇万字长文 聪大脑的预测性编码讲起,区分三种不确定性,最终对我们如何应对这个充满不确定的时代,给出启示。愿读完后,你能够更全面客观的理解生活中的随机性。霍金斯是一位计算机科学家(后来成为…

网站开启https后很慢_网站优化中哪些设置会影响蜘蛛的抓取?对网站SEO产生什么影响...

网站在优化中,要有一定的收录基础才能有更大的几率提升排名,并获得搜索引擎的喜爱。但在网站优化中难免会有一些细节没注意到而影响蜘蛛的抓取,下面就带大家一起了解一下。一、登录设置有些网站会设置注册账号的要求才能允许用户浏览网站&…

正则表达式提取器_C++11新特性7 - 正则表达式

C11 新增了正则表达式的标准库支持&#xff0c;本文简介 C 正则表达式的使用在 C 中使用正则表达式&#xff0c;和其它语言差别不大int main() {regex e("abc*");bool m regex_search("abccc", e);// 输出 yescout << (m ? "yes" : &quo…

智慧城市建设必须认真对待的几个问题(一):IPV6作为地址的问题

全文共计4384字&#xff0c;预计阅读时间9分钟来源 | 数据观&#xff08;转载请注明来源&#xff09;作者 | 陆宝华 李晋 张永红 李学良编辑 | 蒲蒲引言智慧城市已经热炒几年了&#xff0c;目前还在升温&#xff0c;并且一些做国际联网应用的大企业提出了“城市大脑”的概念。当…

linux open 头文件_linux下通过共享内存和mmap实现进程间通讯

前言最近在学习GNU/Linux内核&#xff0c;看到mmap的时候书上说&#xff1a;mmap/munmap接口函数是用户最常用的两个系统调用接口&#xff0c;无论是在用户程序中分配内存、读写大文件、链接动态库文件&#xff0c;还是多进程间共享内存&#xff0c;都可以看到mmap/munmap的身影…

TinyML:下一轮人工智能革命

来源&#xff1a;AI前线作者&#xff1a;Matthew Stewart译者&#xff1a;盖磊策划&#xff1a;陈思人工智能的一个趋势是正快速从“云端”走向“边缘”。TinyML 是在海量的物联网设备端微控制器上实现的人工智能&#xff0c;有望在未来几年内&#xff0c;成为人工智能在工业领…

springboot导入项目依赖报错_最详细的 Spring Boot 多模块开发与排坑指南

来源于公众未读代码 &#xff0c;作者达西呀创建项目创建一个 SpringBoot 项目非常的简单&#xff0c;简单到这里根本不用再提。你可以在使用 IDEA 新建项目时直接选择 Spring Initlalize 创建一个 Spring Boot 项目&#xff0c;也可以使用 Spring 官方提供的 Spring Boot 项目…

图书管理系统html_结自主可控数字化硕果,同方鼎欣推进基于OFD技术的数字档案管理系统研发...

01浅谈建立自主可控版式格式的重要性说起版式文档&#xff0c;相信大家首先想到的就是Adobe公司推出的PDF&#xff0c;这种格式的电子文档&#xff0c;其效果不因软硬件环境变化而变化&#xff0c;在版面、字体、字号方面可以与纸质文件保持一致&#xff0c;这就是版式文档的重…

联结你与万物的8种元素

本文经授权转载自《原理》微信公众号你不仅由元素构成&#xff0c;你其实就是元素。不同元素的原子在你的身体里&#xff0c;它们随你而动&#xff0c;它们与你一同经历成功的狂喜&#xff0c;一同承受失败的悲痛&#xff0c;也一同走过平淡的日常。当你吃下食物时&#xff0c;…

Spring中的用到的设计模式大全

spring中常用的设计模式达到九种&#xff0c;我们举例说明&#xff1a; 第一种&#xff1a;简单工厂又叫做静态工厂方法&#xff08;StaticFactory Method&#xff09;模式&#xff0c;但不属于23种GOF设计模式之一。 简单工厂模式的实质是由一个工厂类根据传入的参数&#xff…

crontab 日志_聊聊老板让我删除日志文件那些事儿

一、背景老板&#xff1a;小白&#xff0c;刚才咱们的机器告警磁盘空间不足了&#xff0c;你去定位一下原因。我&#xff1a;(......空间不足碍我屁事儿)好的&#xff0c;马上定位我&#xff1a;老板&#xff0c;太多N天前的日志文件占用了太多空间。 老板&#xff1a;你感觉你…

【专家观点】刘经南院士:北斗+5G为何能引领新基建?

来源&#xff1a;智能研究院日前&#xff0c;“第四届全球未来出行大会&#xff08;GFM2020&#xff09;”在德清召开。本次大会旨在探讨未来的城市、未来的出行、未来的汽车如何为居民提供更加经济、便捷、安全、科技友好的新出行方式。在论坛的演讲中&#xff0c;中国工程院院…

ae中心点重置工具_(精品)AE从小白到大神之路(七)-AE动画—动效常见的设计方法...

动画——动效常见的设计方法一&#xff0e;基础动画&#xff1a;1.通过物体本身的旋转/缩放/位移/不透明度等基本属性来做的一些动效属于最基础的动画效果。二&#xff0e;路径动画&#xff1a;&#xff08;1&#xff09;修剪路径动画&#xff08;前面系列案例——下载提示完成…

css 透明度_如何使用CSS实现精美视频片头制作

借助CSS所提供的动画效果&#xff0c;旋转效果除了能够制作动画及网页页面元素&#xff0c;如按钮之外&#xff0c;还可以使用CSS实现精美的动态片头的制作。本文主要介绍CSS与HTML实现精美的动画片头制作实例。如何使用CSS实现精美片头制作CSS动态片头设计实例本例设计使用烟雾…

重磅盘点:过去8年中深度学习最重要的想法

原文&#xff1a;Deep Learning’s Most Important Ideas[1]作者&#xff1a;Denny Britz&#xff08;ML 研究员&#xff0c;Google Brain 前成员&#xff09;译者&#xff1a;REN深度学习是一个瞬息万变的领域&#xff0c;层出不穷的论文和新思路可能会令人不知所措。即使是经…

ActiveMQ 发送和接收消息

一、添加 jar 包 <dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-all</artifactId><version>5.11.2</version> </dependency> 二、消息传递的两种形式 1、点对点&#xff1a;发送的消息只能被一个消…

机器人 蓝buff 钩_机器人要在S赛登场了?Ming韩服练起来了,这是RNG黑科技?

随着S9全球总决赛日程的逼近&#xff0c;各大战队也纷纷结束了休假&#xff0c;投入到了紧张的训练之中。对于这次S9世界赛的版本&#xff0c;应该是上中野的版本&#xff0c;因为不少战士单带型上单得到了巨大加强&#xff0c;而且中路会有一些法师英雄回归&#xff0c;总体来…

java构造器_Java类加载的过程

阅读本文约需要8分钟 大家好&#xff0c;我是你们的导师&#xff0c;经常看我朋友圈的同学应该知道&#xff0c;我每天会在微信上给大家免费提供以下服务&#xff01;1、长期为你提供最优质的学习资源&#xff01;2、给你解决技术问题&#xff01;3、每天在朋友圈里分享优质的技…

再讲卷积的本质及物理意义,解释的真幽默!

来源&#xff1a;电子工程专辑编辑 ∑Gemini分三个部分来理解&#xff1a;1&#xff0e;信号的角度2&#xff0e;数学家的理解&#xff08;外行&#xff09;3&#xff0e;与多项式的关系>>>>卷积这个东东是“信号与系统”中论述系统对输入信号的响应而提出的。因为…

分区助手扩大c盘后自动修复_磁盘分区工具,这个好用;无论调整C盘还是系统迁移...

使用傲梅分区助手安全地对磁盘进行分区安全分区注意事项1.对于重要数据&#xff0c;最好习惯定期备份。 您可以使用免费备份软件- 傲梅轻松备份进行备份。2.当傲梅分区助手正在移动数据时&#xff0c;请不要轻易地结束过程或强制关闭程序。3.在分区过程中&#xff0c;请确保您的…