Python多段程和多过程(四) 进程同歩之数据信号
摘要:還是以网络爬虫为例子子。你可以能有那么个要求:目录页爬到许多的可是假如一秒可以爬到30个假如一秒能爬一百个因此,这时开是多少个进程在于一秒能爬好多个可是大家了解,...
還是以网络爬虫为例子子。你可以能有那么个要求:目录页爬到许多的 可是假如一秒可以爬到30个
假如一秒能爬一百个
因此,这时开是多少个进程在于一秒能爬好多个
可是大家了解,进程总数并不是越大就越好,进程数多了,CPU转换进程消耗的時间就多了。
因此,大家期待可以自身操纵进程的总数。
比如,某一进程一秒能爬一百个
from threading import Semaphore,Thread from time import sleep from random import uniform class GetDetailContent(Thread): def __init__(self,sem,detail_url): super(GetDetailContent,self).__init__() self.sem = sem self.url = detail_url def run(self): sleep(uniform(0,1)) # 用sleep仿真模拟抓取,以便呈现进程是完毕一个就转化成一个而并不是10个10个转化成的,这儿设置抓取每一个网页页面的時间是任意的 print("%s 取得成功抓取网页页面 %s" % (self.name,self.url)) # 抓取进行后,释放出来数据信号量,没释放出来1次,电子计数器便会-1;假如电子计数器从满的情况-1,便会唤起acquire() self.sem.release() class GetDetailUrl: def __init__(self,thread_num=10): self.sem = Semaphore(thread_num) # 界定一个数据信号量目标,容许高并发的进程数为10个
for page in range(10): # 假定有10页目录页 for id in range(100): # 每张有一百个url self.sem.acquire() # 数据信号量实行一次acquire便会在self.sem的內部电子计数器里加1,当电子计数器做到容许高并发的进程数时便会进到等候情况 " % id t = GetDetailContent(self.sem,url) # 对每一个 t.start() sleep(1) # 一秒抓取一个目录页
raise ValueError("semaphore initial value must be = 0") self._cond = Condition(Lock()) self._value = value def acquire(self, blocking=True, timeout=None): if not blocking and timeout is not None: raise ValueError("can't specify timeout for non-blocking acquire") rc = False endtime = None with self._cond: while self._value == 0: if not blocking: break if timeout is not None: if endtime is None: endtime = _time() + timeout else: timeout = endtime - _time() if timeout = 0: break self._cond.wait(timeout) else: self._value -= 1 rc = True return rc
数据信号量是用 标准自变量+电子计数器完成的。__init__()的_value纪录了可再次打开进程的数量
每实行一次acquire(),电子计数器_value会-1。但_value为0时,acquire()会启用标准自变量的wait进到休眠状态当实行release()的情况下,电子计数器_value会+1,而且notify唤起wait()促使能够再次打开新进程。
张柏沛IT技术性blog > Python多段程和多过程(四) 进程同歩之数据信号量 点一下拷贝转截该一篇文章
semaphore 数据信号量不但能够操纵进程总数,还能够操纵如mysql联接,互联网联接那样的联接数。