这一节开始介绍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的更多相关文章

  1. vue系列---Mustache.js模板引擎介绍及源码解析(十)

    mustache.js(3.0.0版本) 是一个javascript前端模板引擎.官方文档(https://github.com/janl/mustache.js) 根据官方介绍:Mustache可以 ...

  2. ReactiveSwift源码解析(十) Lifetime代码实现

    为了之后博客的进行,本篇博客我们就来聊一下ReactiveSwift框架中的Lifetime类的具体实现.从Lifetime这个名字中我们就这道,就是生命周期.在ReactiveSwift中使用Lif ...

  3. Android恢复出厂设置流程分析【Android源码解析十】

    最近看恢复出厂的一个问题,以前也查过这方面的流程,所以这里整理一些AP+framework层的流程: 在setting-->备份与重置--->恢复出厂设置--->重置手机---> ...

  4. ReactiveSwift源码解析(十二) MutableProperty基本代码实现

    前两篇博客我们分别聊了ReactiveSwift框架中的负责标记对象的生命周期的类Lifetime以及负责原子性操作的Atomic类的具体代码实现.前两篇博客之所以聊Lifetime以及Atomic的 ...

  5. 第三十六节,目标检测之yolo源码解析

    在一个月前,我就已经介绍了yolo目标检测的原理,后来也把tensorflow实现代码仔细看了一遍.但是由于这个暑假事情比较大,就一直搁浅了下来,趁今天有时间,就把源码解析一下.关于yolo目标检测的 ...

  6. 第十四章 Executors源码解析

    前边两章介绍了基础线程池ThreadPoolExecutor的使用方式.工作机理.参数详细介绍以及核心源码解析. 具体的介绍请参照: 第十二章 ThreadPoolExecutor使用与工作机理 第十 ...

  7. Alink漫谈(十八) :源码解析 之 多列字符串编码MultiStringIndexer

    Alink漫谈(十八) :源码解析 之 多列字符串编码MultiStringIndexer 目录 Alink漫谈(十八) :源码解析 之 多列字符串编码MultiStringIndexer 0x00 ...

  8. Alink漫谈(十九) :源码解析 之 分位点离散化Quantile

    Alink漫谈(十九) :源码解析 之 分位点离散化Quantile 目录 Alink漫谈(十九) :源码解析 之 分位点离散化Quantile 0x00 摘要 0x01 背景概念 1.1 离散化 1 ...

  9. Alink漫谈(二十) :卡方检验源码解析

    Alink漫谈(二十) :卡方检验源码解析 目录 Alink漫谈(二十) :卡方检验源码解析 0x00 摘要 0x01 背景概念 1.1 假设检验 1.2 H0和H1是什么? 1.3 P值 (P-va ...

  10. springboot源码解析-管中窥豹系列之BeanPostProcessor(十二)

    一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...

随机推荐

  1. 【转】Android业务组件化之URL Scheme使用

    前言: 最近公司业务发展迅速,单一的项目工程不再适合公司发展需要,所以开始推进公司APP业务组件化,很荣幸自己能够牵头做这件事,经过研究实现组件化的通信方案通过URL Scheme,所以想着现在还是在 ...

  2. Odoo图片如何显示

    转载请注明原文地址:https://www.cnblogs.com/cnodoo/p/9281423.html odoo没有专门的图片标签,但是可以通过widget来控制field标签来显示图片内容. ...

  3. Apache AB的安装和使用(Ubuntu16.04)

    步骤很简单一共两步,安装一步,使用一步. sudo apt-get install apache2-utils ab -n 10000 -c 100 https://www.baidu.com/ 注意 ...

  4. C语言偏冷知识点汇总

    1.C语言函数声明中参数类型写在右括号后是什么意思?如下代码所示: int add(a, b) int a; int b; { return a + b; } 像这样的声明是什么意思,我测试过在gcc ...

  5. 【vue知识点】1)vue生命周期

    [vue知识点]2)vue登录认证

  6. oracle12c创建用户指定表空间

    --1.创建临时空间 create temporary tablespace zyj_temp tempfile 'D:\app2\user\virtual\oradata\orcl\zyj_temp ...

  7. TopJUI | easyui HTML Dialog页面间GET方式数据传递

    较容易的方式通过URL内带参数进行数据传递 var url = "apddList.html?c0=" + row.uuid + "&c1=" + ro ...

  8. 树莓派 ubuntu 系统下修改config.txt文件调整分辨率记录

    参考 https://www.jianshu.com/p/99eea4db21c4 注:操作前最好先备份个 config.txt 文件 防止悲剧 防止悲剧 防止悲剧 终端下 进入boot/config ...

  9. 使用jieba导入引用方法时,报错AttributeError: module 'jieba' has no attribute 'cut'

    一.问题描述 import jieba导入后,使用jieba.cut()方法时报错AttributeError: module 'jieba' has no attribute 'cut' 二.问题分 ...

  10. docker for windows 使用mssql2017

    原文:docker for windows 使用mssql2017 确实有些坑,本来之前坑都踩过了,但是时间一久就忘记了,这次换电脑又都踩了一遍. 几个要点(坑): 1.docker安装时默认就好.然 ...