iis 应用池超出其作业限制_Python线程和进程池并行编程

v2-19d24858c15404e30518e561e409fb23_1440w.jpg?source=172ae18b
Python 3.2版本之后发布了 concurrent.futures模块,用以支持和管理并发编程,内容涵盖了进程和线程池(Thread and Process Pooling)、非确定性执行流(Nondeterministic Execution Flows)以及进程和线程同步。

v2-aa6a0822ee5d239077f53954909b9db1_b.jpg

本文通过将带有可选参数的任务提交(Submit)给执行器(Executor)来实例化futures对象。执行器是线程或者进程执行池访问的父类,线程或者进程实例的使用比较耗费资源,因此需要尽可能的重复利用资源,提升整体性能。为此Python提供了concurrent.futures模块实现池(Pooling)的概念,并提供了如下的类:

  • concurrent.futures.Executor - 用于异步执行调用;
  • Submit(function, argument) - 调度一个函数的执行
  • map(function, argument) - 异步方式执行函数
  • shutdown(Wait = True) - 通知执行器(Executor)释放资源
  • concurrent.futures.Future - 封装了回调函数的异步执行

如何处理线程或者进程池

线程或进程池(也称为池)表示用于优化和简化程序中线程和/或进程资源管理的软件管理器。通过池化,可以向池中提交要执行的任务。池配备了一个挂起任务的内部队列,以及执行这些任务的多个线程或进程。池中一个重要的概念是重用。线程或进程在其生命周期中多次用于不同的任务。它减少了创建和提高利用池的程序性能的开销。

Executor的子类

重用是致程序员使用池的主要原因之一。concurrent.futures模块提供了executor类的两个子类,它们分别异步操作线程池和进程池。这两个子类如下所示:

  • concurrent.futures.ThreadPoolExecutor(max_workers)
  • concurrent.futures.ProcessPoolExecutor(max_workers)

其中,max_workers参数标识异步执行调用的最大工作线程数。

顺序 vs. 线程/进程池

下面这个例子我们展示了进程和线程池的使用,代码要执行的任务是我们有一个从1到10的数字列表,数字列表。对于列表中的每个元素,一个计数器统计1000万次,目的只是浪费时间。

  • 顺序执行
  • 5个worker的线程池执行
  • 5个worker的进程池执行

我们建立一个存储在number_list中的数字列表,对于列表中的每个元素,我们操作计数过程直到1亿次迭代。然后我们将得到的值乘以1亿。在主程序中,我们执行将以顺序模式执行的任务;在并行模式下,我们将对线程池使用concurrent.futures模块的池功能。线程池执行器使用其内部池线程之一执行给定任务。它管理在其池中工作的文件线程。每个线程从池中取出一个作业并执行它。执行作业时,它将从线程池中接受下一个要处理的作业。处理完所有作业后,将打印执行时间;与threadpoolexecutor类似,processpoolexecutor类是一个executor子类,它使用进程池异步执行调用。然而,与threadpoolexecutor不同,进程池执行器使用multiprocessing模块,这可以跳出全局解释器锁的限制,获得更短的执行时间。

""" Asynchronous Programming """

import concurrent.futures
import time

number_list = [x+1 for x in range(10)]

def count(number):
    for i in range(10_000_000):
        i += 1
    return i * number

def evaluate_item(x):
    result_item = count(x)
    print('item ' + str(x) + ' result ' + str(result_item))

if __name__ == "__main__":
    # Sequential Execution
    start_time = time.clock()
    for n in number_list:
        evaluate_item(n)
    print('Sequential execution in ' + 
      str(time.clock() - start_time), 'seconds')

    # Thread pool Execution
    start_time = time.clock()
    with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
        for n in number_list:
            executor.submit(evaluate_item, n)
    print('Thread pool execution in ' + 
      str(time.clock() - start_time), 'seconds')

    # Process pool Execution
    start_time = time.clock()
    with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
        for n in number_list:
            executor.submit(evaluate_item, n)
    print('Process pool execution in ' + 
      str(time.clock() - start_time), 'seconds')

现在我们打开命令提示符运行python文件,最终我们会得到下面的结果。由于多线程收到GIL的限制,因为是计算密集型速度跟顺序执行相差不大,但在IO密集型的应用中,多线程比顺序执行会限制提升性能;多进程由于摆脱了GIL的限制,充分利用了CPU的资源,并行度最高,也获得更多的性能提升。

$ python pooling_with_concurrent_futures.py
item 1 result 10000000
item 2 result 20000000
item 3 result 30000000
item 4 result 40000000
item 5 result 50000000
item 6 result 60000000
item 7 result 70000000
item 8 result 80000000
item 9 result 90000000
item 10 result 100000000
Sequential execution in 7.084029 seconds
item 1 result 10000000
item 2 result 20000000
item 4 result 40000000
item 5 result 50000000
item 3 result 30000000
item 7 result 70000000
item 6 result 60000000
item 10 result 100000000
item 8 result 80000000
item 9 result 90000000
Thread pool execution in 6.836254 seconds
item 4 result 40000000
item 1 result 10000000
item 3 result 30000000
item 5 result 50000000
item 2 result 20000000
item 6 result 60000000
item 7 result 70000000
item 9 result 90000000
item 8 result 80000000
item 10 result 100000000
Process pool execution in 0.0213239999999999 seconds

结束语

在几乎所有需要处理大量客户端同时请求的服务器应用程序中,都会使用池技术。不过,许多应用程序要求任务应该立即执行,或者在需要对线程有更多的控制权的情况下,池并不是最佳选择。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值