yocto-sumo源码解析(十): ProcessServer.idle_commands
这一节开始介绍ProcessServer.idle_commands,前面我们知道ProcessServer.main就是不停调用idle_commands()以获取可用的套接字描述符或者是文件描述符来进行处理。
def idle_commands(self, delay, fds=None):
nextsleep = delay #设置本函数的下次睡眠延迟
if not fds:
fds = [] for function, data in list(self._idlefuns.items()): #遍历_idlefuns,逐个调用其中的函数,注李意这里一个技巧,拷贝构造了_idlefuns列表,如果不拷贝直接使用,那么循环体内的删除操作将会出错
try:
retval = function(self, data, False)
if retval is False: #函数返回值为False,也就是一个逻辑假的时候,从列表中删除这个函数,并设置nextsleep为None
del self._idlefuns[function]
nextsleep = None
elif retval is True: #函数返回值为True,也就是逻辑真的时候,设置nextsleep为None,注意这里不删除所调用的函数,那么我们可以理解为,一个函数被持续调用,直至其返回值为假
nextsleep = None
elif isinstance(retval, float) and nextsleep: #若返回值为浮点类型,那么认为这个函数返回的是一个时延,选择一个较小时延给nextsleep
if (retval < nextsleep):
nextsleep = retval
elif nextsleep is None: #nextsleep为None,那么直接进入下一个函数的处理流程
continue
else: #否则认为函数返回一个文件描述符列表
fds = fds + retval
except SystemExit:
raise
except Exception as exc:
if not isinstance(exc, bb.BBHandledException):
logger.exception('Running idle function')
del self._idlefuns[function]
self.quit = True
#上面循环主要是做两件事:一件事是调用所有idlefunc,第二件是找到一个最小的nextsleep # Create new heartbeat event?
now = time.time()
if now >= self.next_heartbeat: #当前事件比心跳时间迟,认为丢失了心跳
# We might have missed heartbeats. Just trigger once in
# that case and continue after the usual delay.
self.next_heartbeat += self.heartbeat_seconds
if self.next_heartbeat <= now:
self.next_heartbeat = now + self.heartbeat_seconds #计算出一个新的心跳延迟,保障新的心跳延迟一定是在将来
heartbeat = bb.event.HeartbeatEvent(now)
bb.event.fire(heartbeat, self.cooker.data) #触发新的心跳
if nextsleep and now + nextsleep > self.next_heartbeat: #睡眠以后可能错过新的心跳,因此这里缩短睡眠时间
# Shorten timeout so that we we wake up in time for
# the heartbeat.
nextsleep = self.next_heartbeat - now if nextsleep is not None: #在睡眠周期内找到可用的文件描述符,这里需要对select有一定了解
if self.xmlrpc:
nextsleep = self.xmlrpc.get_timeout(nextsleep)
try:
return select.select(fds,[],[],nextsleep)[0]
except InterruptedError:
# Ignore EINTR
return []
else:
return select.select(fds,[],[],0)[0]
从上面的代码分析中,可以看出来,ProessServer.main()中的ready是从fds或者是xmlrpc中选出来的,回首前程往事:
fds = [self.sock]
if self.xmlrpc:
fds.append(self.xmlrpc)
只要sock就绪,那么就会进入到ready列表。
这里接下来看看_idlefuns这个列表到底是些什么函数呢?ProcessServer在构造函数中初始是置空的,但是提供了一个函数去注册idlefun:
def __init__(self, lock, sock, sockname):
multiprocessing.Process.__init__(self)
self.command_channel = False
self.command_channel_reply = False
self.quit = False
self.heartbeat_seconds = 1 # default, BB_HEARTBEAT_EVENT will be checked once we have a datastore.
self.next_heartbeat = time.time() self.event_handle = None
self.haveui = False
self.lastui = False
self.xmlrpc = False self._idlefuns = {} self.bitbake_lock = lock
self.sock = sock
self.sockname = sockname def register_idle_function(self, function, data):
"""Register a function to be called while the server is idle"""
assert hasattr(function, '__call__')
self._idlefuns[function] = data
进而在ProcessServer.start中将该函数传递到configuration对象:
def _startServer(self):
print(self.start_log_format % (os.getpid(), datetime.datetime.now().strftime(self.start_log_datetime_format)))
server = ProcessServer(self.bitbake_lock, self.sock, self.sockname)
self.configuration.setServerRegIdleCallback(server.register_idle_function)
......
cookerdata.py:
def setServerRegIdleCallback(self, srcb):
self.server_register_idlecallback = srcb
通篇检索yocto-sumo,系统共注册了下面函数:_process_inotify_updates,buildFileIdle,buildTargetsIdle,runCommands
下回再对这些函数进行分说。
yocto-sumo源码解析(十): ProcessServer.idle_commands的更多相关文章
- vue系列---Mustache.js模板引擎介绍及源码解析(十)
mustache.js(3.0.0版本) 是一个javascript前端模板引擎.官方文档(https://github.com/janl/mustache.js) 根据官方介绍:Mustache可以 ...
- ReactiveSwift源码解析(十) Lifetime代码实现
为了之后博客的进行,本篇博客我们就来聊一下ReactiveSwift框架中的Lifetime类的具体实现.从Lifetime这个名字中我们就这道,就是生命周期.在ReactiveSwift中使用Lif ...
- Android恢复出厂设置流程分析【Android源码解析十】
最近看恢复出厂的一个问题,以前也查过这方面的流程,所以这里整理一些AP+framework层的流程: 在setting-->备份与重置--->恢复出厂设置--->重置手机---> ...
- ReactiveSwift源码解析(十二) MutableProperty基本代码实现
前两篇博客我们分别聊了ReactiveSwift框架中的负责标记对象的生命周期的类Lifetime以及负责原子性操作的Atomic类的具体代码实现.前两篇博客之所以聊Lifetime以及Atomic的 ...
- 第三十六节,目标检测之yolo源码解析
在一个月前,我就已经介绍了yolo目标检测的原理,后来也把tensorflow实现代码仔细看了一遍.但是由于这个暑假事情比较大,就一直搁浅了下来,趁今天有时间,就把源码解析一下.关于yolo目标检测的 ...
- 第十四章 Executors源码解析
前边两章介绍了基础线程池ThreadPoolExecutor的使用方式.工作机理.参数详细介绍以及核心源码解析. 具体的介绍请参照: 第十二章 ThreadPoolExecutor使用与工作机理 第十 ...
- Alink漫谈(十八) :源码解析 之 多列字符串编码MultiStringIndexer
Alink漫谈(十八) :源码解析 之 多列字符串编码MultiStringIndexer 目录 Alink漫谈(十八) :源码解析 之 多列字符串编码MultiStringIndexer 0x00 ...
- Alink漫谈(十九) :源码解析 之 分位点离散化Quantile
Alink漫谈(十九) :源码解析 之 分位点离散化Quantile 目录 Alink漫谈(十九) :源码解析 之 分位点离散化Quantile 0x00 摘要 0x01 背景概念 1.1 离散化 1 ...
- Alink漫谈(二十) :卡方检验源码解析
Alink漫谈(二十) :卡方检验源码解析 目录 Alink漫谈(二十) :卡方检验源码解析 0x00 摘要 0x01 背景概念 1.1 假设检验 1.2 H0和H1是什么? 1.3 P值 (P-va ...
- springboot源码解析-管中窥豹系列之BeanPostProcessor(十二)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
随机推荐
- performSelector 多参调用的实现方案
1.nsinvocation封装: 2.msg_send封装: 第二种方案是系统的原生封装.
- 1050. [HAOI2006]旅行【并查集+枚举】
Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T,求 一条路径,使得路径上最 ...
- 2018年1月12日--微信小程序----出错报告(40kb的原因)---并解决方法
一. 报错的原因是因为,图片的文件太大了,已经超过了40kb...不能超过40kb. 在这里查看图片文件的大小:
- springboot项目打war包pom设置
<build> <finalName>PayManager</finalName><!--打包后的名字PayManager.war--> <plu ...
- JDK(十)JDK1.7&1.8源码对比分析【集合】ConcurrentHashMap
前言 在JDK1.7&1.8源码对比分析[集合]HashMap中我们对比分析了JDK1.7和1.8版本的HashMap源码,趁热打铁,这篇文章就来看看JDK1.7和1.8版本的Concurre ...
- P1070 道路游戏
题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将这 n 个机器人工厂编 ...
- python执行时遇到 KeyError: b'somevar' 时需要想到的
虽然这个问题很小,但我觉得很有必要单独拿出来强调一下. 这样在遇到类似错误的时候可以很快反应过来,进而节约了时间. 这里我拿 shelve 模块举例(shelve的作用大致就是把python变量存放到 ...
- Get與Post的區別--總結隨筆
關於Get與Post的區別的文章,在網上太多了:有優點有缺點,今天我給各位大哥做一個總結性的隨筆,還請多多包涵~ 首先是W3School上的答案,請查收: GET在浏览器回退时是无害的,而POST会再 ...
- golang中的字符串拼接
go语言中支持的字符串拼接的方法有很多种,这里就来罗列一下 常用的字符串拼接方法 1.最常用的方法肯定是 + 连接两个字符串.这与python类似,不过由于golang中的字符串是不可变的类型,因此用 ...
- 4.Operators-操作符(Dart中文文档)
Dart有如下操作符: Description Operator unary postfix expr++ expr-- () [] . ?. unary prefix -expr !expr ~ex ...