semaphore
内部维护了一个条件变量condition
,构造函数是:
Semaphore(value=1) # value设置是内部维护的计数器的大小,默认为1.
主要有两个方法:
每当调用acquire()时,内置计数器-1,直到为0的时候阻塞每当调用release()时,内置计数器+1,并让某个线程的acquire()从阻塞变为不阻塞
用爬虫来举例,假如说有一个UrlProducer
线程,爬取url
,多个htmlSpider
线程,爬取url
对应的网页。如果直接开20个htmlSpider
线程,20个线程是同时执行的,现在要限制同时执行能执行三个,就可以使用信号量来控制:
import threadingimport timeclass 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通知acquireclass 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()
从结果可以看出,每次都几乎是三个同时的完成任务。
init方法
sepaphoren init方法.png
Semaphore
类的构造函数传入接收一个参数value
,设置内部计数器的大小。调用release()
时将这个值加1,调用acquire()
时减1。
wait方法
wait方法.png
wait
方法并不复杂,每次调用acquire
,内部技术器就减1,当计数器为0的时候,就等待通知。
release方法
sepaphoren release方法.png
在看release
方法的时候,突然发现,条件变量的notify
方法,在没有线程等待的时候,也是可以调用的,不用抛出异常。所以这里不用判断内部计数器是不是0,而是每次都可以调用notify
。
信号量semaphore
可以控制同时运行执行的线程数量。
信号量semaphore
内部维护了一个条件变量和一个计数器。
联系客服