Python 限制线程的最大数量的方法(Semaphore)

Python 中通过 Semaphore 对象可以限制线程的最大数量,从而控制线程的并发访问。Semaphore 是一种同步工具,用于保证多个线程间访问资源的顺序或安全性。

Semaphore在Python的Threading模块中实现。Semaphore维护了一个内部计数器,初始提供一个数量参数,来限制并发线程访问的数量。当我们希望限制一定数量的线程访问共享资源时,可以创建一个 Semaphore 对象,并将计数器初始化为限额值。每当线程获取资源时,Semaphores的计数器就减少一。当计数器值为 0 时,任何尝试获取资源的线程都将被阻塞。

具体来看,Semaphore 的使用方法如下:

创建一个Semaphore对象

import threading

# 创建一个Semaphore对象,并指定信号量的数量
semaphore = threading.Semaphore(3)  # 限制最大并发数量为3

获取锁

获取Semaphore信号量时,可以使用semaphore.acquire()方法,这个方法会判断当前的 Semaphore 对象信号量计数器是否大于0,如果大于0,则立即减少信号量计数器的值并返回True,否则线程会被阻塞。

# 获取 Semaphore,信号量-1
semaphore.acquire()
# ...
# 访问共享资源
# ...
# 释放 Semaphore,信号量+1
semaphore.release()

释放锁

释放Semaphore锁时,需要使用semaphore.release() 方法。Semaphore的计数器会增加1,使得其他线程可以获取信号量访问共享资源。

# 释放 Semaphore,信号量+1
semaphore.release()

示例1

import time
import threading

semaphore = threading.Semaphore(3) # 最大并发数量为3

def worker():
    with semaphore:
        print(f'{threading.current_thread().name} 获取到信号量')
        time.sleep(1) # 模拟执行操作
        print(f'{threading.current_thread().name} 释放信号量')

threads = []
for i in range(5):
    t = threading.Thread(target=worker, name=f'thread-{i}')
    t.start()
    threads.append(t)

for t in threads:
    t.join()

在上面的代码中,我们创建了一个Semaphore对象,设置最大并发数量为3。创建了5个线程,同时在每个线程中获取 Semaphore 对象,打印线程名和时间戳,然后睡眠1s,接着释放 Semaphore 对象,打印线程名和时间戳。

输出结果:

thread-0 获取到信号量
thread-1 获取到信号量
thread-2 获取到信号量
thread-1 释放信号量
thread-3 获取到信号量
thread-2 释放信号量
thread-0 释放信号量
thread-4 获取到信号量
thread-3 释放信号量
thread-4 释放信号量

示例2

另一个使用Semaphore来限制最大并发的例子是运用在爬虫中。爬虫是我们需要获取公共资源的应用之一。比如我们需要获取一个网站中很多商品的数据,如果我们同时向网站发出大量的请求,就容易被网站屏蔽。这个时候使用Semaphore可以很好的避免这个问题,代码可以这样实现:

import requests
import threading

class Crawler:
    SEMAPHORE = threading.Semaphore(3)

    def __init__(self, item):
        self.item = item

    def run(self):
        with self.SEMAPHORE:
            print(f'开始爬取商品{self.item}')
            # 发送请求
            response = requests.get(f'https://www.example.com/products?item={self.item}')
            # 解析数据
            data = self.parse_data(response.text)
            # 保存数据
            self.save_data_to_database(data)
            print(f'商品{self.item}爬取完毕')

    def parse_data(self, data):
         # 爬虫解析数据的具体逻辑
        pass

    def save_data_to_database(self, data):
         # 爬虫保存数据到数据库的具体逻辑
        pass

items = ['item1', 'item2', 'item3', 'item4', 'item5', 'item6']
crawlers = [Crawler(item) for item in items]

threads = [threading.Thread(target=crawler.run, args=()) for crawler in crawlers]
for thread in threads:
    thread.start()

for thread in threads:
    thread.join()

在这个例子中,我们首先创建了一个Semaphore对象并设置最大并发数量为3。然后我们创建了Crawler 类,该类代表了一个爬虫任务,随后在run方法中实现了具体的爬虫逻辑。在 run方法中首先获取Semaphore对象,获取到信号量时打印开始爬取一个商品的信息,随后发送请求,解析数据,保存数据到数据库。完成以上操作之后,释放Semaphore对象,打印结束爬取一个商品的信息。

我们创建了6个Crawler对象,分别代表了需要爬取的6个商品,最后在多线程的环境中运行爬虫。Semaphore对象可以限制最大并发数量,保证在同一时间内只有3个爬虫工作,不会让网站服务被过于频繁的访问。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python 限制线程的最大数量的方法(Semaphore) - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • 基于Python代码实现Apriori 关联规则算法

    基于Python代码实现Apriori 关联规则算法 Apriori算法是一种常用的关联规则挖掘算法,它可以从大规模数据集中挖掘出频繁项集和关联规则。在Python中,可以使用多种库来实现Apriori算法,包括mlxtend、pyfpgrowth等。本文将详细讲解基于Python代码实现Apriori关联规则算法的完整攻略,包括算法原理、Python实现过…

    python 2023年5月13日
    00
  • python中列表(list)和元组(tuple)的深入讲解

    Python中列表(List)和元组(Tuple)的深入讲解 Python中的列表(List)和元组(Tuple)是两种常用的数据类型,它们都可以用来存储多个元素。本文将深入讲解Python中列表和元组的区别、创建、访问、修改、删除等操作,并提供两个示例说明。 列表(List)和元组(Tuple)的区别 列表和元组的最大区别在于它们的可变性。列表是可变的,可…

    python 2023年5月13日
    00
  • Python常用编译器原理及特点解析

    Python常用编译器原理及特点解析 什么是编译器? 编译器是一种将高级语言代码转换为机器语言可执行文件的程序。简而言之,编译器是将编写好的程序转换为计算机能够理解的语言。 Python的编译过程 Python是一种解释型语言,不需要编译过程,但是为了执行效率,Python也可以通过编译来提高运行速度。 Python编译分两个阶段:源码编译和字节码编译。 源…

    python 2023年5月18日
    00
  • Python操作mongodb数据库的方法详解

    下面是“Python操作mongodb数据库的方法详解”的完整攻略: 目录 准备工作 连接MongoDB数据库 插入文档 查询文档 更新文档 删除文档 示例说明 示例一:插入一条文档 示例二:查询所有文档并打印出来 准备工作 为了能够使用Python操作mongodb数据库,我们需要先安装pymongo库。可以使用pip进行安装: pip install p…

    python 2023年5月14日
    00
  • python 将Excel转Word的示例

    下面是一份完整的Python将Excel转Word的示例教程。 1. 安装依赖库 需要使用到 openpyxl 和 python-docx 两个Python依赖库,需要先进行安装: pip install openpyxl python-docx 2. 编写代码 下面是一个简单的示例,将Excel中的数据转成表格插入到Word文件中: import open…

    python 2023年5月13日
    00
  • 详解Python常用标准库之时间模块time和datetime

    详解Python常用标准库之时间模块time和datetime 简介 time 和 datetime 是 Python 中常用的时间模块。 time 模块提供了一些操作时间的函数,包括获取当前时间、休眠等功能。 datetime 模块提供了更高级的时间处理功能,包括日期和时间的加减、格式化等。 time 模块 时间戳和结构化时间 在 time 模块中,我们会…

    python 2023年5月14日
    00
  • 在Python 3中实现类型检查器的简单方法

    下面就是详细讲解“在Python 3中实现类型检查器的简单方法”的攻略。 概述 Python 是一种动态弱类型的语言,使得在编写程序时出现错误的可能性增大,尤其是涉及到类型的错误。在 Python 3 中,我们可以通过类型注释来对变量、函数的参数和返回值进行标注,然后利用第三方模块 mypy 实现类型检查。 步骤 第一步:安装 mypy 在命令行中输入以下指…

    python 2023年5月13日
    00
  • Python figure参数及subplot子图绘制代码

    下面就对这个问题进行详细讲解。 1. Python中的figure参数 在Python的matplotlib库中,figure参数指代的是整个图形对象的定义,它可以控制图形的大小、分辨率、背景色等属性。首先需要创建一个figure对象,然后在对象上进行绘图即可。 下面给出一个示例代码,展示如何创建一个figure对象: import matplotlib.p…

    python 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部