Python自定义线程池实现方法分析

2023-12-15Python编程
8

Python自定义线程池实现方法分析

什么是线程池?

线程池是一个线程队列,当有任务到来时,就会将任务加入队列中,线程池内的线程就会去队列中获取任务并执行。线程池的主要优势在于减少了线程的频繁创建和销毁的操作,提升了程序的效率。

Python线程池的实现

Python中线程池的实现需要用到两个模块,分别是threadingqueue

  1. threading模块用来实现线程池中执行任务的线程。
  2. queue模块用来实现线程池的任务队列。

以下是线程池的实现方法:

import queue
import threading

class ThreadPool:
    def __init__(self, max_workers):
        self._max_workers = max_workers
        self._job_queue = queue.Queue()
        self._workers = []

    def submit(self, func, *args, **kwargs):
        self._job_queue.put((func, args, kwargs))
        if len(self._workers) < self._max_workers:
            worker = threading.Thread(target=self._worker_thread)
            worker.start()
            self._workers.append(worker)

    def _worker_thread(self):
        while True:
            try:
                func, args, kwargs = self._job_queue.get(True)
            except:
                break
            func(*args, **kwargs)
            self._job_queue.task_done()

    def wait_completion(self):
        self._job_queue.join()

上述代码中,ThreadPool类维护了一个任务队列_job_queue和一组线程_workerssubmit方法用来向线程池中提交任务,在队列中添加元组(func, args, kwargs),其中func是待执行的函数,argskwargs是用于调用函数的参数。如果线程池还有空余的线程,会将一个新线程加入到_workers列表中。_worker_thread方法是实际执行任务的方法,当线程从队列中取出元组,会调用其中的函数func(*args, **kwargs)wait_completion方法用于等待所有任务执行完毕。

示例说明

示例1

以下代码是一个简单的例子,演示如何使用自定义的线程池执行多个任务。

from time import sleep

def task(num):
    sleep(1)
    print(f'Task {num} is executing...')

if __name__ == '__main__':
    thread_pool = ThreadPool(max_workers=3)
    for i in range(10):
        thread_pool.submit(task, i)
    thread_pool.wait_completion()

上述代码中,自定义了一个task函数,它会执行等待1秒钟后输出一个执行信息。在if __name__ == '__main__':判断中,创建了一个ThreadPool对象,最多同时执行3个任务。接着循环加入了10个任务,这些任务会被添加到任务队列中并且被线程池中的线程执行。最后等待所有的任务执行完成。

示例2

以下代码演示了如何使用自定义线程池爬取多个网站的内容。

import requests

URLS = [
    'http://www.baidu.com',
    'http://www.sohu.com',
    'http://www.163.com',
    'http://www.qq.com',
    'http://www.taobao.com',
    'http://www.jd.com'
]

def fetch_url(url):
    response = requests.get(url, timeout=10)
    print(f'{url}: {len(response.text)} bytes')

if __name__ == '__main__':
    thread_pool = ThreadPool(max_workers=3)
    for url in URLS:
        thread_pool.submit(fetch_url, url)
    thread_pool.wait_completion()

上述代码中,定义了一个fetch_url函数,它会根据指定的url发起网络请求,并输出响应的长度信息。在if __name__ == '__main__':判断中,创建了一个ThreadPool对象,最多同时执行3个任务。接着循环遍历网站列表并加入队列中,然后线程池中的线程会去获取这些任务并执行。输出每个网站的响应长度信息。最后等待所有任务执行完成。

总结

本文介绍了Python自定义线程池的实现方法,并且通过两个示例演示了如何使用。线程池的实现需要用到threadingqueue两个模块。使用自定义线程池可以有效地减少线程的频繁创建和销毁的操作,提升程序的效率。

The End

相关推荐

解析Python中的eval()、exec()及其相关函数
Python中有三个内置函数eval()、exec()和compile()来执行动态代码。这些函数能够从字符串参数中读取Python代码并在运行时执行该代码。但是,使用这些函数时必须小心,因为它们的不当使用可能会导致安全漏洞。...
2023-12-18 Python编程
117

Python下载网络文本数据到本地内存的四种实现方法示例
在Python中,下载网络文本数据到本地内存是常见的操作之一。本文将介绍四种常见的下载网络文本数据到本地内存的实现方法,并提供示例说明。...
2023-12-18 Python编程
101

Python 二进制字节流数据的读取操作(bytes与bitstring)
来给你详细讲解下Python 二进制字节流数据的读取操作(bytes与bitstring)。...
2023-12-18 Python编程
120

Python3.0与2.X版本的区别实例分析
Python 3.x 是 Python 2.x 的下一个重大版本,其中有一些值得注意的区别。 Python 3.0中包含了许多不兼容的变化,这意味着在迁移到3.0之前,必须进行代码更改和测试。本文将介绍主要的差异,并给出一些实例来说明不同点。...
2023-12-18 Python编程
34

python如何在终端里面显示一张图片
要在终端里显示图片,需要使用一些Python库。其中一种流行的库是Pillow,它有一个子库PIL.Image可以加载和处理图像文件。要在终端中显示图像,可以使用如下的步骤:...
2023-12-18 Python编程
91

Python图像处理实现两幅图像合成一幅图像的方法【测试可用】
在Python中,我们可以使用Pillow库来进行图像处理。具体实现两幅图像合成一幅图像的方法如下:...
2023-12-18 Python编程
103