美文网首页Python
[python] 线程间同步之信号量Semaphore

[python] 线程间同步之信号量Semaphore

作者: StormZhu | 来源:发表于2018-05-05 17:14 被阅读0次

用处

信号量semaphore 是用于控制进入数量的锁。有哪些应用场景呢,比如说在读写文件的时候,一般只能只有一个线程在写,而读可以有多个线程同时进行,如果需要限制同时读文件的线程个数,这时候就可以用到信号量了(如果用互斥锁,就是限制同一时刻只能有一个线程读取文件)。又比如在做爬虫的时候,有时候爬取速度太快了,会导致被网站禁止,所以这个时候就需要控制爬虫爬取网站的频率。

实例

semaphore内部维护了一个条件变量condition,构造函数是:

Semaphore(value=1) # value设置是内部维护的计数器的大小,默认为1. 

主要有两个方法:

每当调用acquire()时,内置计数器-1,直到为0的时候阻塞
每当调用release()时,内置计数器+1,并让某个线程的acquire()从阻塞变为不阻塞

用爬虫来举例,假如说有一个UrlProducer线程,爬取url,多个htmlSpider线程,爬取url对应的网页。如果直接开20个htmlSpider线程,20个线程是同时执行的,现在要限制同时执行能执行三个,就可以使用信号量来控制:

import threading
import time
class htmlSpider(threading.Thread):
    def __init__(self, url, sem):
        super().__init__()
        self.url = url
        self.sem = sem

    def run(self):
        time.sleep(2)
        print("got html text success")
        self.sem.release() # 内部维护的计数器加1,并通知内部维护的conditon通知acquire

class UrlProducer(threading.Thread):
    def __init__(self, sem):
        super().__init__()
        self.sem = sem

    def run(self):
        for i in range(20):
            self.sem.acquire() # 内部维护的计数器减1,到0就会阻塞
            html_thread = htmlSpider("http://baidu.com/{}".format(i), self.sem)
            html_thread.start()

if __name__ == "__main__":
    sem = threading.Semaphore(3) #设置同时最多3个
    url_producer = UrlProducer(sem)
    url_producer.start()

从结果可以看出,每次都几乎是三个同时的完成任务。

源码分析

  1. init方法

    sepaphoren init方法.png
    Semaphore类的构造函数传入接收一个参数value,设置内部计数器的大小。调用release()时将这个值加1,调用acquire()时减1。
  2. wait方法

    wait方法.png
    wait方法并不复杂,每次调用acquire,内部技术器就减1,当计数器为0的时候,就等待通知。
  3. release方法

    sepaphoren release方法.png
    在看release方法的时候,突然发现,条件变量的notify方法,在没有线程等待的时候,也是可以调用的,不用抛出异常。所以这里不用判断内部计数器是不是0,而是每次都可以调用notify

    总结

    • 信号量semaphore 可以控制同时运行执行的线程数量。
    • 信号量semaphore内部维护了一个条件变量和一个计数器。

    参考

    1. Python3高级编程和异步IO并发编程

相关文章

  • [python] 线程间同步之信号量Semaphore

    用处 信号量semaphore 是用于控制进入数量的锁。有哪些应用场景呢,比如说在读写文件的时候,一般只能只有一个...

  • 一篇文章理清Python多线程之同步条件,信号量和队列

    今天这篇文章大概介绍下python多线程中的同步条件Event,信号量(Semaphore)和队列(queue),...

  • 线程同步

    1.dispatch_semaphore(信号量)的理解及使用2.iOS 多线程同步策略之-----锁NSLock...

  • GCD篇

    dispatch_semaphore(信号量) 语法解析 保持线程同步 为线程加锁 宏定义 dispatch_sy...

  • JUC下线程同步类

    这些类为JUC包,他们都起到线程同步作用 Semaphore(信号量) 在现实场景,Semaphore的实现,比如...

  • 线程同步之使用信号量semaphore

    线程同步之使用信号量semaphore 基本概念 信号量:信号量就是一个整数,并且具有一个初始计数值。支持两个操作...

  • 信号量Semaphore

    Semaphore(信号量) 是一个线程同步结构,用于在线程间传递信号,以避免出现信号丢失(译者注:下文会具体介绍...

  • 【Redisson】Semaphore 锁源码剖析

    Semaphore 也是 Redis 分布式锁支持的一种,同步组件。 Semaphore 信号量:允许多个线程同时...

  • 信号量和互斥锁的区别

    信号量和互斥锁: 信号量(semaphore[ˈseməfɔ:(r)])用在多线程多任务同步的,一个线程完成了某一...

  • JAVA多线程-Semaphore信号量

    一、概述 Semaphore(信号量) 是一个线程同步结构,用于在线程间传递信号,以避免出现信号丢失,或者像锁一样...

网友评论

    本文标题:[python] 线程间同步之信号量Semaphore

    本文链接:https://www.haomeiwen.com/subject/mrrerftx.html