Python multiprocessing.Pool与threadpool

前言

在写Python多进程的时候使用了进程池来自动以规定进程数执行完任务,比较方便,自动类比到多线程有没有线程池.
最先找到的是是from gevent import threadpool,语法和进程池一模一样,但是!,它并不是想象中的线程池,而是线程组池,教程太少没太细究.反正是达不到效果.

进程池

以下是进程池示例:

import multiprocessing

def multi_app(mod=0, msg=0):
    pass
    
def test_process_pool(process_num=4, task_num=100000):
    pool = multiprocessing.Pool(processes=process_num)
    for i in range(task_num):
        pool.apply_async(multi_app, (1, i,))  # 维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
    pool.close()  # join函数等待所有子进程结束
    pool.join()  # 调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool

线程池

然后经过一番查找,发现网上对于线程池基本都是两个策略:

  • 自己实现
  • threadpool模块
    自己实现自己写过,比较简单,但是效率嘛还有些不尽人意
    这是自己粗略的测试:
    这里写图片描述
    所以打算研究研究threadpool模块.
    其实作为Python的一个模块,使用也不算容易了:
  • threadpool.makeRequests()方法设置线程池待处理的线程
  • pool.putRequest()方法开启线程
    而且还在传参常遇到了麻烦,网上找一圈,都是一个参跑多个线程,或者多个参跑两个线程,却找不到多个参跑任意多线程的.那坑出在哪呢?
    正常threading.Thread(target=multi_app, args=(1, 1,))中target传入目标函数,args传入所有参数即可
    但是threadpool.makeRequests(callable_=multi_app, args_list=request_list)中args_list参数不是简单的传入所有参数的Tuple就行:
import threadpool

def multi_app(mod=0, msg=0):
    pass

def test_thread_pool(thread_num=1, task_num=1000):
    request_list=[]
    pool = threadpool.ThreadPool(thread_num)
    for i in range(task_num):
        request_list.append(([1,i],None))
    requests = threadpool.makeRequests(callable_=multi_app, args_list=request_list)
    # [pool.putRequest(req) for req in requests]
    map(pool.putRequest, requests)
    pool.wait()

总结
普通的多参传递多是横向传递,简单的一维数组控制参数传递,而makeRequests()方法的数组比较复杂,它的一维列表控制线程任务数量,而第二维才是传参,例如(([1,1],None),([2,2],None),([3,3],None))在一般传参时传入三个参数,分别是([1,1],None),([2,2],None),([3,3],None)三个数组,在makeRequests()方法中则是传入两个参数,设定了三个线程任务threadpool.makeRequests()方法则返回了一个任务列表,pool.putRequest()方法启动线程时可以for迭代或者相较稍高效的map()方法.

你可能感兴趣的:(Python,编程语言)