多处理基础
生成秒的最简单方法是使用目标函数实例化 Process对象并调用start() 使其开始工作。
import multiprocessing
def worker ():
"""worker function"""
print 'Worker'
return
if __name__ == '__main__' :
jobs = []
for i in range ( 5 ):
p = multiprocessing 。处理(目标=工人)
工作。追加( p )
p 。开始()
输出包括打印了五次的“Worker”这个词,尽管根据执行顺序它可能并不完全干净。
$蟒蛇multiprocessing_simple.py
工人
,工人
,工人
,工人
,工人
能够产生一个带有参数的进程来告诉它要做什么通常更有用。与线程不同,要将参数传递给多处理 进程,参数必须能够使用pickle进行序列化。这个例子传递给每个工人一个数字,所以输出更有趣一些。
import multiprocessing
def worker ( num ):
"""thread worker function"""
print 'Worker:' , num
return
if __name__ == '__main__' :
jobs = []
for i in range ( 5 ):
p = multiprocessing 。处理( target = worker , args = ( i ,))
作业。追加( p )
p. 开始()
整数参数现在包含在每个工作人员打印的消息中:
$ python multiprocessing_simpleargs.py
工人:0
工人:1
工人:2
工人:3
工人:4
可导入的目标函数
在之间的一个区别线程和多处理 的例子是额外的保护__main__在使用 多处理的例子。由于新进程的启动方式,子进程需要能够导入包含目标函数的脚本。将应用程序的主要部分包装在对__main__的检查中,确保它不会在导入模块时在每个子项中递归运行。另一种方法是从单独的脚本中导入目标函数。
例如,这个主程序:
import multiprocessing
import multiprocessing_import_worker
if __name__ == '__main__' :
jobs = []
for i in range ( 5 ):
p = multiprocessing 。处理(目标= multiprocessing_import_worker 。工人)
的作业。追加( p )
p 。开始()
使用这个工作函数,定义在一个单独的模块中:
def worker ():
"""worker function"""
print 'Worker'
return
并产生与上面第一个示例类似的输出:
$蟒蛇multiprocessing_import_main.py
工人
,工人
,工人
,工人
,工人
确定当前进程
传递参数来标识或命名过程很麻烦,而且没有必要。每个Process实例都有一个带有默认值的名称,可以在创建流程时更改该名称。命名进程对于跟踪它们很有用,尤其是在同时运行多种类型进程的应用程序中。
import multiprocessing
import time
def worker ():
name = multiprocessing . current_process () 。名称
打印 名称, “开始”
时间。sleep ( 2 )
打印 名称, '退出'
def my_service ():
name = multiprocessing 。current_process () 。名称
打印 名称, “开始”
时间。睡觉(3 )
打印 名称, '退出'
如果 __name__ == '__main__' :
service = multiprocessing 。Process ( name = 'my_service' , target = my_service )
worker_1 = multiprocessing 。进程( name = 'worker 1' , target = worker )
worker_2 = multiprocessing 。进程(目标=工人) # 使用默认名称
worker_1 。开始()
worker_2 。启动()
服务。开始()
调试输出的每一行都包含当前进程的名称。名称列中带有Process-3的行对应于未命名的进程worker_1。
$ python multiprocessing_names.py
worker 1 启动
worker 1 退出
进程3 启动
进程3 退出
my_service 启动
my_service 退出
守护进程
默认情况下,直到所有子程序都退出后,主程序才会退出。有时启动后台进程运行时不会阻止主程序退出是很有用的,例如在可能没有简单方法中断工作程序的服务中,或者在工作过程中让它死掉不会丢失或损坏数据(例如,为服务监控工具生成“心跳”的任务)。
要将进程标记为守护进程,请使用布尔值设置其守护进程属性。默认情况下,进程不是守护进程,因此传递 True 会打开守护进程模式。
import multiprocessing
import time
import sys
def daemon ():
p = multiprocessing . current_process ()
打印 'Starting:' , p 。姓名, 页码。pid
系统。标准输出。冲洗()
时间。sleep ( 2 )
打印 'Exiting:' , p 。姓名, 页码。pid
系统。标准输出。flush ()
def non_daemon ():
p = multiprocessing 。current_process ()
打印 'Starting:' , p 。姓名, 页码。pid
系统。标准输出。flush ()
打印 'Exiting :' , p 。姓名, 页码。pid
系统。标准输出。flush ()
if __name__ == '__main__' :
d = multiprocessing. 进程( name = 'daemon' , target = daemon )
d . 守护进程 = 真
n = 多处理。进程( name = 'non-daemon' , target = non_daemon )
n 。守护进程 = 假
d . 开始()
时间。睡眠( 1 )
n 。开始()