python是如何实现进程池和线程池的_python笔记46:进程池详解与应用

主要内容:

  • 小目标:掌握进程池
  • 主要内容:进程池使用;

1. 进程池:

有没有一种方式:直接创建N个进程,然后直接将任务交给这些进程去执行?
有,进程池;

进程池相关方法:

60b6d55b553793de07ddb1e22f9eceaa.png

进程池

apply_async与apply区别:

  • apply:添加任务后,等待进程函数执行完,
  • apply_async:添加任务后,立即返回,支持回调;原型如下:
#callback为回调函数pools.apply_async(func, args=(), kwds={},    callback=None, error_callback=None,)

直接看例子:

from multiprocessing import Poolimport timeimport osdef func(*args, **kwargs):    # 定义进程函数    print('sub process id:', os.getpid())    time.sleep(1)if __name__ == "__main__":    start = time.time()    # 创建进程池,进程数为4    pools = Pool(4)    for i in range(5):        # 添加任务        pools.apply_async(func)    # 关闭进程池,不在添加任务    pools.close()    pools.join()    print("cost time:", int(time.time()-start))

结果:

sub process id: 15536sub process id: 2788sub process id: 20288sub process id: 11020sub process id: 15536cost time: 2

2. 进程池处理结果获取方式;

一个例子:统计句子中有效单词数量;

#6个单词,长度为20wds = "this is test this is test"

2.1 思路1:ApplyResult

实现思路:

创建进程池;

对wds进程切分,每个单词为wd;

添加任务,每个进程函数统计每个wd长度,并返回长度;

通过ApplyResult接收

代码实现:

from multiprocessing import Poolimport timeimport osdef func(*args, **kwargs):    # 定义进程函数    val = args[0]    return len(val)if __name__ == "__main__":    wds = "this is test this is test"    # 创建进程池,进程数为4    pools = Pool(4)    listr = []    # 切分字符串,并进程长度统计    for wd in wds.split():        # 添加任务,返回ApplyResult        r = pools.apply_async(func, args=(wd,))        listr.append(r)    # 关闭进程池,不在添加任务    pools.close()    pools.join()    # 通过ApplyResult获取长度    lens = 0    for r in listr:        lens += r.get()    print('wds lens:', lens)

结果:

wds lens: 20

2.2 思路2:回调函数

  • 回调函数:将函数作为参数传递给其他函数,当这个函数被调用时,就被称为回调函数;
  • 通过设置apply_async中的callback;

实现思路:

创建进程池;

对wds进程切分,每个单词为wd;

定义回调函数,参数为单词长度,操作计算单词长度累积和;

添加任务,每个进程函数统计每个wd长度,并指定回调函数;

通过回调函数进行长度统计

代码实现:

from multiprocessing import Poolimport timeimport osdef func(*args, **kwargs):    # 定义进程函数    val = args[0]    return len(val)glens = 0def callback(val):    global glens    glens += valif __name__ == "__main__":    wds = "this is test this is test"    # 创建进程池,进程数为4    pools = Pool(4)    listr = []    # 切分字符串,并进程长度统计    for wd in wds.split():        # 添加任务,返回ApplyResult        r = pools.apply_async(func, args=(wd,), callback=callback)        listr.append(r)    # 关闭进程池,不在添加任务    pools.close()    pools.join()    print('glens:', glens)

结果:glens: 20

分析:callback在进程函数执行完之后进行调用;

总结

进程池优点:

一次性创建N多进程,减少系统常见进程开销;

使用灵活,接口简单;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值