python多进程实例详解

写在前面:python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情。借助这个包,可以轻松完成从单进程到并发执行的转换。

1.multiprocessing模块提供了一个Process类来代表一个进程对象

 

import os
import time
import multiprocessing
def run_proc(name): # 子进程要执行的代码
    print '运行子进程 %s ,子进程号为(%s)...' % (name, os.getpid())
    print "我的处理内容是:%s+%s=?" % (name,name)
    return name

if __name__=='__main__':
    start = time.time()
    print '父进程号为 %s.' % os.getpid()
    print('----------------------------------------')
    job = []
    for i in range(3):
        p = multiprocessing.Process(target=run_proc, args=(i,))#多进程
        job.append(p)
        print '子进程%d开启...'%i
        p.start() #
        print '子进程%d结束...'    %i
        print
#加join()可以让主线程一直等待全部的子线程结束之后,主线程自身才结束,程序退出
for t in job: t.join()#join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步 end = time.time() print end-start

运行结果如下:

父进程号为 4924.
----------------------------------------
子进程0开启...
子进程0结束...

子进程1开启...
子进程1结束...

子进程2开启...
运行子进程 0 ,子进程号为(5516)...
我的处理内容是:0+0=?
运行子进程 1 ,子进程号为(5517)...
我的处理内容是:1+1=?
运行子进程 2 ,子进程号为(5523)...
我的处理内容是:2+2=?
子进程2结束...

0.0220789909363

如果想要返回多进程process处理得到的结果,只需要利用multiprocessing 中的Manager类即可,稍改代码:

import os
import time
from multiprocessing import Manager
def run_proc(name,return_list): # 子进程要执行的代码
    print '运行子进程 %s ,子进程号为(%s)...' % (name, os.getpid())
    print "我的处理内容是:%s+%s=?" % (name,name)
    return_list.append(name)

if __name__=='__main__':
    print '父进程号为 %s.' % os.getpid()
    print('----------------------------------------')
    
    manager = Manager()
    return_list = manager.list() 
    #return_dict = manager.dict() 也可以使用字典dict
    job = []
    for i in range(3):
        p = multiprocessing.Process(target=run_proc, args=(i,return_list))#多进程
        job.append(p)
        print '子进程%d开启...'%i
        p.start()
        print '子进程%d结束...'    %i
        print
    for t in job:
        t.join()
    print "所有子进程处理得到的结果都在return_list中,值为:",return_list

运行结果如下:

父进程号为 4924.
----------------------------------------
子进程0开启...
子进程0结束...

子进程1开启...
子进程1结束...

子进程2开启...
运行子进程 0 ,子进程号为(5614)...
我的处理内容是:0+0=?
运行子进程 1 ,子进程号为(5616)...
我的处理内容是:1+1=?
运行子进程 2 ,子进程号为(5623)...
我的处理内容是:2+2=?
子进程2结束...

所有子进程处理得到的结果都在return_list中,值为: [0, 1, 2]

 

2.Pool:如果要启动大量的子进程,可以用进程池的方式批量创建子进程:

from multiprocessing import Pool
import os, time, random

def long_time_task(name):
    print '运行任务 %s ,子进程号为(%s)...' % (name, os.getpid())
    
    print "我就是子进程号为(%s)处理的内容" % (os.getpid())
    start = time.time()
    time.sleep(random.random() * 3)
    end = time.time()
    print '任务 %s 运行了 %0.2f 秒.' % (name, (end - start))
    return name

if __name__=='__main__':
    print '父进程号为 %s.' % os.getpid()
    rst = []
    p = Pool(4)  #进程池中含有4个子进程
    for i in range(5): #4个子进程完成5个任务,所以有一个任务是需要等某个进程空闲再处理
        a = p.apply_async(long_time_task, args=(i,)) #a是进程处理函数long_time_task的返回结果
        rst.append(a)  #将次得到的结果添加到数组rst中去
    print '等待所有子进程结束...'
    p.close()
    p.join()#等待所有子进程执行完毕。调用join()之前必须先调用close(),调用close()之后就不能继续添加新的Process了。
    print '所有子进程结束...'

运行结果如下:

父进程号为 3378.
运行任务 0 ,子进程号为(4621)...
运行任务 2 ,子进程号为(4624)...
运行任务 1 ,子进程号为(4622)...
我就是子进程号为(4621)处理的内容
我就是子进程号为(4622)处理的内容
运行任务 3 ,子进程号为(4627)...
我就是子进程号为(4624)处理的内容
我就是子进程号为(4627)处理的内容
任务 1 运行了 0.16 秒.
运行任务 4 ,子进程号为(4622)...
我就是子进程号为(4622)处理的内容
等待所有子进程结束...
任务 2 运行了 0.98 秒.
任务 4 运行了 0.89 秒.
任务 3 运行了 2.25 秒.
任务 0 运行了 2.89 秒.
所有子进程结束...

直接输出rst不会得到想要的结果:

rst
运行结果:
[<multiprocessing.pool.ApplyResult at 0x7ffa6c682c90>,
 <multiprocessing.pool.ApplyResult at 0x7ffa6c587590>,
 <multiprocessing.pool.ApplyResult at 0x7ffa6c587610>,
 <multiprocessing.pool.ApplyResult at 0x7ffa6c5876d0>,
 <multiprocessing.pool.ApplyResult at 0x7ffa6c587790>]

这是需要用到.get()方法:

rst = [i.get() for i in rst]
rst
运行结果:
[0, 1, 2, 3, 4]

 

转载于:https://www.cnblogs.com/USTC-ZCC/p/11230827.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值