这一节开始介绍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. python第二课——数据类型1

    day02(上午)主要讲了进制问题,小编之前已经发过了 day02(下午): 1.数据类型: 分类: 1).整数型:int浮点型(小数):float布尔型(True/False):bool 2).字符 ...

  2. 动态代理与HOOK(与oc isa 替换)

    HOOK:面向函数,解决函数调用拦截与替换的问题: 动态代理:面向对象,解决对象的动态替换问题: 动态代理的实现方案: 1.经典代理机制: 2.子类化机制:oc语言的isa替换是这额解决方案的经典案例 ...

  3. 2049. [SDOI2008]Cave 洞穴勘测【LCT】

    Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...

  4. [SCOI2007]组队

    嘟嘟嘟 这题有人说部分分O(n3)暴力,然而我暴力都没写过,调了半天也没用……还是看题解吧 首先,咱把A * ( h – minH ) + B * ( s – minS ) <= C 变个型,得 ...

  5. C#根据淘宝接口网址获取客户端访问IP和网络运营商

    网络运营商会为每台联网的电脑分配公网IP,如何获取它们?? 话不多说直接上代码: using System; using System.Collections.Generic; using Syste ...

  6. P1880 [NOI1995]石子合并

    题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...

  7. HDU 2602 Bone Collector(经典01背包问题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2602 Bone Collector Time Limit: 2000/1000 MS (Java/O ...

  8. Angular动态表单生成(五)

    动态表单生成之布局 到上面的篇章为止,我们已经把表单比较完整的生成出来了,也实现了一些验证功能,可以说,我们截止这里,就已经可以满足我们的大部分表单生成需求了~ 但是: 目前来说,我们对于表单的布局只 ...

  9. 【转】C++三大特性

    又重新看了一个多月的书,也算是基本上了解了一些很基础的东西,学习C++就得掌握它所具备的三大特性. 封装性是基础,继承性是关键,多态性是补充,并且多态性存在于继承的环境中. 封装性 C++语言中支持数 ...

  10. 解决安装macports更新失败问题

       安装 macports 先是卡在开始,xcode的路径指定错误,重新指定一下,然后再sudo port selfupdate,就卡再ports.tar那里不动了.经过google和百度查到参考网 ...