线程池&进程池

Posted zx125

tags:

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

线程池&进程池

池子解决什么问题?

1.创建/销毁线程伴随着系统开销,如果过于频繁会影响系统运行效率
2.线程并发数量过多,抢占系统资源,从而导致系统阻塞甚至死机
3.能够刚好的控制和管理池子里面的线程和进程

concurrent.futures模块提供了高度封装的异步调用接口

ThreadPoolExecutor:线程池,提供异步调用

ProcessPoolExecutor:进程池,提供异步调用

常用方法

submit(fn, *args, **kwargs):异步提交任务

map(func, *iterables, timeout=None, chunksize=1):取代for循环submit的操作

shutdown(wait=True):相当于进程池的pool.close()+pool.join()操作

? wait=True,等待池内所有任务执行完毕回收完资源后才继续

? wait=False,立即返回,并不会等待池内的任务执行完毕

? 但不管wait参数为何值,整个程序都会等到所有任务执行完毕

? submit和map必须在shutdown之前

result(timeout=None):取得结果

add_done_callback(fn):回调函数

done():判断某一个线程是否完成

cancle():取消某个任务

例1 基本用法

from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor

import os,time,random
def work(i):
    print(f"work-i搬了一块砖头")
    time.sleep(1)
    return "zx"
if __name__ == '__main__':

    executor=ProcessPoolExecutor(max_workers=3)

    #工人们
    futures=[]

    for i in range(11):
        future=executor.submit(work,i)
        futures.append(future)

    #线程池shutdown 关闭入口,等待所有任务结束
    executor.shutdown(True)

    #打印执行的结果
    for future in futures:
        print(future.result())
work-0搬了一块砖头
work-1搬了一块砖头
work-2搬了一块砖头
work-3搬了一块砖头
work-4搬了一块砖头
work-5搬了一块砖头
work-6搬了一块砖头
work-7搬了一块砖头
work-8搬了一块砖头
work-9搬了一块砖头
work-10搬了一块砖头
zx
zx
zx
zx
zx
zx
zx
zx
zx
zx
zx

注意这样用会是不对的

from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor

import os,time,random
def work(i):
    print(f"work-i搬了一块砖头")
    time.sleep(1)
    return "zx"
if __name__ == '__main__':

    executor=ProcessPoolExecutor(max_workers=3)

    for i in range(11):
        future=executor.submit(work,i)
        print(future.result())
work-0搬了一块砖头
zx
work-1搬了一块砖头
zx
work-2搬了一块砖头
zx
work-3搬了一块砖头
zx
work-4搬了一块砖头
zx
work-5搬了一块砖头
zx
work-6搬了一块砖头
zx
work-7搬了一块砖头
zx
work-8搬了一块砖头
zx
work-9搬了一块砖头
zx
work-10搬了一块砖头
zx

例2 基础线程池加回调用法

from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import threading
import time,random

def work(i):
    #获取当前线程对象
    thread = threading.current_thread()
    print(f"thread.getName()搬了第i块砖头")
    time.sleep(random.randint(1,3))
    return i

def call_back(zx):
    res = zx.result()
    print(res)

if __name__ == '__main__':
    #线程池为可装线程3个
    executor=ThreadPoolExecutor(max_workers=3)

    for i in range(11):
        executor.submit(work,i).add_done_callback(call_back)
ThreadPoolExecutor-0_0搬了第0块砖头
ThreadPoolExecutor-0_1搬了第1块砖头
ThreadPoolExecutor-0_2搬了第2块砖头
0
ThreadPoolExecutor-0_0搬了第3块砖头
2
ThreadPoolExecutor-0_2搬了第4块砖头
1
ThreadPoolExecutor-0_1搬了第5块砖头
3
ThreadPoolExecutor-0_0搬了第6块砖头
5
ThreadPoolExecutor-0_1搬了第7块砖头
4
ThreadPoolExecutor-0_2搬了第8块砖头
6
ThreadPoolExecutor-0_0搬了第9块砖头
9
ThreadPoolExecutor-0_0搬了第10块砖头
7
8
10

例3 进程池加回调函数

from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import time,random,os

def work(i):
    #打印当前进程pid
    print(f"os.getpid()搬了第i块砖头")
    time.sleep(random.randint(1,3))
    return i

def call_back(zx):
    res = zx.result()
    print(res)

if __name__ == '__main__':
    #线程池为可装线程3个
    executor=ProcessPoolExecutor(max_workers=3)

    for i in range(11):
        executor.submit(work,i).add_done_callback(call_back)
18696搬了第0块砖头
22500搬了第1块砖头
4172搬了第2块砖头
22500搬了第3块砖头
1
22500搬了第4块砖头
3
18696搬了第5块砖头
0
4172搬了第6块砖头
2
22500搬了第7块砖头
4
18696搬了第8块砖头
5
18696搬了第9块砖头
8
4172搬了第10块砖头
6
7
9
10

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

python基础33——进程池&线程池/协程

12 并发编程-(线程)-线程queue&进程池与线程池

刷题线程与进程 & 线程池

Python-线程池进程池,协程

进程池与线程池

进程池线程池