• 欢迎访问金笔头博客,这是一个菜鸟(伪)程序员的自留地,欢迎访问我的github:点击进入

线程池的简单用法

python eason 296次浏览 0个评论 扫描二维码

前言

面向对象开发中,大家知道创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。无节制的创建和销毁线程是一种极大的浪费。那我们可不可以把执行完任务的线程不销毁而重复利用呢?仿佛就是把这些线程放进一个池子,一方面我们可以控制同时工作的线程数量,一方面也避免了创建和销毁产生的开销。答案当然是可以的!下面代码就是一个简单的实现。

代码

#!/usr/bin/env python3.6
# -*- coding: utf-8 -*- 
# software: PyCharm
# file: 4.thread_pool_usage.py
# Created by eason on 2018/4/4 13:19
# site: jinbitou.net
# contact: wang.eason2016@gmail.com
import threading
import time
from queue import Queue


def f(n):
    """
    需要多线程执行的目标函数
    :param n:
    :return:
    """
    print('我执行完需要{}秒钟'.format(n))
    time.sleep(n)


class Worker(threading.Thread):
    def __init__(self, queue):
        super(Worker, self).__init__()
        self.q = queue
        self.daemon = True  # 将线程声明为守护线程
        self.start()

    def run(self):
        while 1:
            # 从队列中删除并返回一个待执行任务
            f, args, kwargs = self.q.get()
            try:
                print(self.name)
                f(*args, **kwargs)  # 执行传进来的方法
            except Exception as e:
                print(e)
            self.q.task_done()


class ThreadPool(object):
    """
    保证同时thread_num个线程在工作
    """
    def __init__(self, thread_num=10):  # 默认10个线程
        self.q = Queue(thread_num)
        # 创建工作线程
        for i in range(thread_num):
            Worker(self.q)

    def add_task(self, f, *args, **kwargs):
        self.q.put((f, args, kwargs))  # 向队列中添加一个任务

    def wait_complete(self):
        self.q.join()  # 阻塞直到所有任务都被执行完毕


if __name__ == '__main__':
    start = time.time()
    pool = ThreadPool(5)  # 五个线程
    for i in range(10):  # 执行f方法10次
        pool.add_task(f, 3)  # 每次3秒
    pool.wait_complete()
    end = time.time()
    print('耗时:{}'.format(end-start))

输出

Thread-1
Thread-2
Thread-3
Thread-4
Thread-5
我执行完需要3秒钟
我执行完需要3秒钟
我执行完需要3秒钟
我执行完需要3秒钟
我执行完需要3秒钟
Thread-2
Thread-4
我执行完需要3秒钟
Thread-1
我执行完需要3秒钟
Thread-5
我执行完需要3秒钟
我执行完需要3秒钟
Thread-3
我执行完需要3秒钟
耗时:6.0032639503479

Process finished with exit code 0

单个方法执行时间为3秒钟,这里执行10次,单线程的话程序总耗时应该是30秒,而这里使用线程池,同时只有5个线程在执行,可以看到线程1到线程5被重复使用了。

更多代码请移步Github:https://github.com/leeyis/python-snippets

有账户的不妨star一下啦~


金笔头博客, 版权所有丨如未注明 , 均为原创, 转载请注明线程池的简单用法
喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址