进程池,线程池,协程

Posted gredae

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程池,线程池,协程相关的知识,希望对你有一定的参考价值。

进程池、线程池、协程

池子有什么作用

在池子创建的时候就将设置的数量创建出来。之后所有的操作都由池子里的进程/线程完成。

当并发的任务数量远远大于计算机所能承受的范围,限制我进程数或线程数,从保证服务器运行。

concurrent.future模块

  • concurrent.future模块封装了线程池与进程池
  • ProcessPoolExecutor(max_works)对于进程池如果不写max_works:默认的是处理器个数
  • ThreadPoolExecutor(max_works)对于线程池如果不写max_works:默认的是处理器个数*5

常用方法

  • result :获得回调函数返回的值
  • submit :相当于apply_async方法
  • shutdown :相当于close+join方法
  • add_done_callback :为当前任务绑定一个回调函数

进程池

from  concurrent.futures import ProcessPoolExecutor
import time,random
def task(n):
    for i in range(100):
        n += i   # 计算密集型的,一般用进程,可以充分利用多核优势
    return n**2
if __name__ == '__main__':
    start = time.time()
    p = ProcessPoolExecutor()
    for i in range(10):
        obj = p.submit(task,i).result()  # 等同于apply同步方法
        print(obj)
    p.shutdown()
    print(time.time() - start)
##############################
# 结果:
0.23636794090270996

线程池

from  concurrent.futures import ProcessPoolExecutor
import time
def task(n):
    time.sleep(3)   # IO密集型的,一般用线程
    return n**2
if __name__ == '__main__':
    start = time.time()
    p = ProcessPoolExecutor()
    for i in range(10):
        obj = p.submit(task,i).result()  # 等同于apply同步方法
    p.shutdown()
    print(time.time() - start)
##############################
# 结果:
30.011648893356323

使用回调函数

进程池
from  concurrent.futures import ProcessPoolExecutor
import time,random
def parse(future)
    print(future.result())
    
def task(n):
    for i in range(100):
        n += i   # 计算密集型的,一般用进程,可以充分利用多核优势
    return n**2

if __name__ == '__main__':
    start = time.time()
    p = ProcessPoolExecutor()
    for i in range(10):
        obj = p.submit(task,i)  # 等同于apply_async同步方法
        obj.add_done_callback(parse)  # 绑定函数,当当前任务结束时调用绑定方法
    p.shutdown()
    print(time.time() - start)
##############################
# 结果:
0.2219409942626953
线程池
from  concurrent.futures import ProcessPoolExecutor
import time
def parse(future):
    print(future.result())
def task(n):
    time.sleep(3)   # IO密集型的,一般用线程
    return n**2
if __name__ == '__main__':
    start = time.time()
    p = ProcessPoolExecutor()
    for i in range(10):
        obj = p.submit(task,i)  # 等同于apply同步方法
        obj.add_done_callback(parse)
    p.shutdown()
    print(time.time() - start)
##############################
# 结果:
9.223718166351318

协程

  • 单线程下实现并发(IO密集型提高效率)

  • 并发的本质:切换+保存状态
  • 降低单个线程的IO时间

简单的协程
from gevent import monkey
monkey.patch_all() #实现捕获非gevent的io
import gevent

import time
def eat():
    print('eat 1')
    time.sleep(2)
    print('eat 2')
def play():
    print('开始运算')
    for i in range(1,10000):
        while i:
            i -= 1
    print('结束运算')

start = time.time()
# play()
# eat()
# 串行执行需要4.417968988418579
g1 = gevent.spawn(eat)
g2 = gevent.spawn(play)
g1.join()
g2.join()
end = time.time()
print(end-start)  # 2.4216597080230713

以上是关于进程池,线程池,协程的主要内容,如果未能解决你的问题,请参考以下文章

python-进程池与线程池,协程

Python-线程池进程池,协程

Python 37 进程池与线程池 协程

进程池线程池 协程

进程池与线程池协程协程实现TCP服务端并发IO模型

Event事件进程池与线程池协程