本文主要介绍Python的进程和进程池,有一定的参考价值。感兴趣的朋友可以参考一下,希望能帮到你。
目录
Python全局变量问题守护程序进程池摘要中的进程进程和程序进程进程创建进程的状态
进程
它是操作系统分配资源的基本单位,也是程序隔离的边界。
进程和程序
程序只是一组指令。它没有运行的意义。它是静态的。
程序的执行实例是动态的,有自己的生命周期,被创建或取消,暂时存在。
流程和程序不是一一对应的。一个程序可以对应多个进程,一个进程也可以执行一个或多个程序。
我们可以这样理解:完成的代码在不运行的时候叫做程序,运行的代码会启动一个(或多个)进程。
进程的状态
在我们的操作系统中工作时,任务的数量往往高于cpu核的数量,即有的任务正在执行,有的任务在等待cpu,这就导致了进程的状态不同。
就绪状态:满状态,等待cpu执行。
执行状态:cpu正在执行。
等待状态:等待某些条件,如程序睡眠,进入等待状态。
Python中的进程
在Python中,进程是由多重处理多重处理模块创建的,该模块提供了一个进程类来创建进程对象。
创建进程
Process语法结构:
流程(组、目标、名称、参数、变量)
Group:指定进程组,在大多数情况下小于。
Target:表示调用对象,即子进程要执行的任务。
名称:子流程的名称,可以为空。
Args:传递给target指定的函数的参数作为元组传递。
Kwargs:将命名参数传递给target指定的函数。
Process常用方法
P.start()启动进程并调用子进程中的p.run()方法。
P.join(timeout):主进程等待进程结束后再结束,timeout是可选的超时。
Is_alive():确定进程是否仍处于活动状态。
p.run()在进程启动时运行的方法,它调用target指定的函数。
页(page的缩写)terminate()是最后一个进程。
Process创建的实例对象的常属性
名称:当前进程的别名。默认值为Process-N,N是从1开始递增的整数。
Pid:当前进程的pid(进程号)
导入多重处理
导入操作系统
导入时间
定义工作(名称):
打印('子流程工作正在运行.')
时间.睡眠(0.5)
打印(姓名)
#获取进程的名称
Print('子进程名',multi processing . current _ process())
#获取进程的pid
Print('子进程PID ',multi processing . current _ process()。PID,OS.getPID())
#获取父进程的pid
Print('父进程pid ',os.getppid())
打印('子进程运行结束.')
if __name__=='__main__ ':
打印(“主流程开始”)
#获取进程的名称
Print('主进程名',multi processing . current _ process())
#获取进程的pid
Print('主进程PID ',multi processing . current _ process()。PID,OS.getPID())
#创建流程
p=多重处理。Process(group=None,target=work,args=('tigeriaf ',))
#开始流程
开始()
打印(“主流程结束”)
通过上面的代码,我们发现多重处理。Process帮助我们创建了一个子流程,并且成功运行了。但是,我们发现主进程在子进程结束之前就已经死亡了,所以这个子进程在主进程结束之后就是一个孤儿进程。那么,我们可以要求主流程等待子流程结束后再结束吗?答案是肯定的。也就是通过p.join(),join()的作用就是让主进程等待子进程执行完再退出。
导入多重处理
导入操作系统
导入时间
定义工作(名称):
打印('子流程工作正在运行.')
时间.睡眠(0.5)
打印(姓名)
#获取进程的名称
Print('子进程名',multi processing . current _ process())
#获取进程的pid
Print('子进程PID ',multi processing . current _ process()。PID,OS.getPID())
#获取父进程的pid
Print('父进程pid ',os.getppid())
打印('子进程运行结束.')
if __name__=='__main__ ':
打印(“主流程开始”)
#获取进程的名称
Print('主进程名',multi processing . current _ process())
#获取进程的pid
Print('主进程PID ',multi processing . current _ process()。PID,OS.getPID())
#创建流程
p=多重处理。Process(group=None,target=work,args=('tigeriaf ',))
#开始流程
开始()
连接()
打印(“主流程结束”)
运行结果:
可以看出,只有在子进程结束后,主进程才结束。
全局变量问题
全局变量不在多个进程间共享,进程间的数据是独立的,默认互不影响。
导入多重处理
#定义全局变量
数字=99
定义工作1():
打印('工作1正在运行.')
Global num #声明函数内部的全局变量num。
数字=数字1 #为数字值输入1
打印(' work1 num={} '。格式(数字))
定义工作2():
打印('工作2正在运行.')
打印(' work2 num={} '。格式(数字))
if __name__=='__main__ ':
#创建流程p1
p1=多重处理。流程(组=无,目标=工作1)
#开始流程p1
p1.start()
#创建流程p2
p2=多重处理。流程(组=无,目标=工作2)
#开始流程p2
p2.start()
运行结果:
从结果中可以看出,work1()函数对全局变量num的修改在work2中没有得到,仍然是原来的99,所以进程共享变量是不够的。
守护进程
如上所述,可以使用p.join()让主进程等待子进程结束后再结束。可以让子进程在主进程结束的时候结束吗?答案是肯定的。我们可以使用p.daemon=True或p2.terminate()来设置它:
导入多重处理
导入时间
定义工作1():
打印('工作1正在运行.')
时间.睡眠(4)
打印(“工作1完成运行”)
定义工作2():
打印('工作2正在运行.')
时间.睡眠(10)
打印(“工作2完成运行”)
if __name__=='__main__ ':
#创建流程p1
p1=多重处理。流程(组=无,目标=工作1)
#开始流程p1
p1.start()
#创建流程p2
p2=多重处理。流程(组=无,目标=工作2)
#设置p2守护进程
#第一种
# p2.daemon=True在start()之前设置,否则会抛出异常。
#开始流程p2
p2.start()
时间.睡眠(2)
Print('主进程已经运行完毕!')
#第一种
p2.terminate()
执行结果如下:
由于守护主进程设置在p2,主进程运行后,p2子进程也会结束,work2任务会停止,work1会继续运行直到结束。
进程池
当要创建的进程数量较少时,multiprocessing.可以直接动态生成多个进程但是,如果要创建许多流程,工作量将会非常大。这时候你可以去多处理模块提供的池创建一个进程池。
multiprocessing.Pool常函数:
Apply_async(func,args,kwds):make func的阻塞模式(任务并行执行),args是传递给func的参数列表,kwds是传递给func的关键字参数列表。
Apply(func,args,kwds):要实现阻塞调优func,您必须等待上一个进程完成其任务,然后才能执行下一个进程。只需要知道就可以了,几乎没有必要。
Close():关闭池,使其不接受新任务。
Terminate():不管任务完成与否,都是完成了。
Join():主进程被阻塞,等待进程的退出,这必须在close或terminate之后进行。
初始化池时,您可以指定最大进程数。当一个新任务提交到池中时,如果进程池未满,将创建一个新进程来执行该任务。但是,如果进程池已满(池中的进程数已达到指定的最大值),任务将等待,直到池中有进程,然后将创建一个新的进程来执行。
从多处理导入池
导入时间
定义工作(一):
打印('工作' { 0 } '正在执行.'。格式(一),多重处理。current _ process()。名字,多重处理。current _ process()。pid)
时间.睡眠(2)
打印('工作' { 0 } '已完成.'。格式(一))
if __name__=='__main__ ':
#创建一个进程池
# Pool(3)表示创建一个容量为3个进程的进程池。
池=池(3)
对于范围(10)内的I:
#进程池同步执行work任务,进程池中的进程会等待上一个进程完成任务后再执行下一个进程。
# pool.apply(work,(I,))
#让work任务异步执行
pool.apply_async(work,(I,))
#进程池关闭后,将不接受任何新请求。
pool.close()
#等待po中所有子流程完成必须放在close()之后。如果work任务是异步执行的,那么主线程将不再等待线程结束就退出!
pool.join()
执行结果为:
结果,我们可以看到只有三个子流程在执行任务。这里我们使用asynchronous(pool . apply _ async(work,(I,)来执行工作任务。如果是同步执行(pool.apply(work,(I,)进程池中的进程会等待上一个进程完成任务后再执行下一个进程。
总结
本文只介绍什么是进程,进程和程序的关系,进程的创建和使用,进程池的创建等。但是没有介绍进程同步和进程通信,这将在下一篇文章中介绍。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。