poky:单个任务是如何被执行的
2011-11-02 15:11
183 查看
* 范围
本文忽略了任务的依赖及其他处理,仅讨论单个任务是如何被执行的。
* 简介:
任务是定义在bb文件中的python/shell函数,代表了软件包build过程中的一个步骤。Bitbake约定,任务名必须以’do_‘开
始,bitbake提供任务的分析和处理机制,具体的任务由bbclass/bbfile提供。
* 前情提要:
Bitbake以Server/UI的方式运行,Server端负责等待并执行命令,UI端负责提交命令并回显结果,二者通过一个双向命令管道
和一个状态队列进行交互。Server决定何时执行什么命令,而命令的具体执行由Cooker负责,这种机制通过回调函数实现。
以bzip2为例,执行以下命令时:
$ bitbake bzip2
1)Bitbake分析命令行得到:cmdline={'action': ['buildTargets', ['bzip2'], 'build'], 'msg': None};
2)UI调用server.runCommand(cmdline['action']),把命令传递给Server;
3)Server交给cooker处理,cooker.buildTargets()被执行,它把自己定义的方法buildTargetsIdle()注册到Server的_idlefunctions列表;
4)Server轮询并执行异步命令,控制权交还给buildTargetsIdle(),故事从这里开始了...
* 任务执行:
Bitbake中任务是一个对象,任务的表现形式是TaskData实例。TaskData可以添加,删除任务,处理任务的各种依赖,但是不能执行任务。
任务的执行依靠RunQueue实现, RunQueue是一个状态机,根据当前所处状态执行相应的操作,RunQueue初始化时状态为”runQueueSceneInit“。
从buildTargetsIdle()开始分析, '->'表示函数/方法的调用关系:
-> rq.execute_runqueue():
该方法执行runqueue队列中的任务,在初始状态下,它调用的是RunQueueExecuteScenequeue实例的execute()方法:
945 self.rqexe = RunQueueExecuteScenequeue(self)
948 retval = self.rqexe.execute()
-> RunQueueExecuteScenequeue.execute()
运行队列中的任务,每一个任务都不是单独存在的,若干任务构成了一条任务链,每个可执行任务最终要通过以下方式被执行:
1602 pid, pipein, pipeout = self.fork_off_task(fn, realtask, taskname)
-> RunQueueExecuteScenequeue.fork_off_task(): 这是一个Wrapper,下面才是真正的fork_off_task()
-> RunQueueExecute.fork_off_task():
先检查和设置任务执行的环境和相关变量,任务的Flag:[umask/fakeroot]就是在这里处理的; 执行任务调用如下方法:
1160 bb.build.exec_task
-> bb.build._exec_task(): 执行任务要比单独执行一个函数复杂一些,仍然需要处理任务相关的环境变量和数据;然后剥去任务的外衣,把它当做函数处理:
321 exec_func(task, localdata)
-> bb.build.exec_func(): 处理任务的其他Flags,根据任务类型(python/shell)分而治之;
170 if ispython:
171 exec_func_python(func, d, runfile, cwd=adir)
172 else:
173 exec_func_shell(func, d, runfile, cwd=adir)
a. -> bb.build.exec_func_python(): 如果任务是python函数:
200 utils.better_exec(comp, {"d": d}, code, bbfile)
-> bb.utils.better_exec(): python类型的任务最终由python内置函数exec执行:
343 exec(code, _context, context)
b. -> bb.build.exec_func_shell():如果任务是shell函数:
243 bb.process.run(cmd, shell=False, stdin=NULL, log=logfile)
-> bb.process.run():把函数转换成命令并返回命令的输出:
95 pipe = Popen(cmd, **options) # subprocess.Popen(), 有关Popen()详细使用请参考subprocess模块的help信息。
至此一个任务执行完毕。
* 总结:
Bitbake中用TakeDate,RunQueueData组织任务数据,而且任务处理过程中还涉及到了数据缓存,日志和事件信息的处理,它们
在BB中被抽象成了不同的类型和对象,希望以后能逐步分析,最终形成一个完整的BB对象类型系统说明。
* 参考:
$ bitbake bzip2 # 部分输出
NOTE: Resolving any missing task queue dependencies
NOTE: Preparing runqueue
NOTE: Executing SetScene Tasks
NOTE: Running setscene task 97 of 277 (/home/wenzong/sdb2/poky/meta/recipes-extended/bzip2/bzip2_1.0.6.bb:do_populate_sysroot_setscene)
NOTE: package bzip2-1.0.6-r3: task do_populate_sysroot_setscene: Started
NOTE: package bzip2-1.0.6-r3: task do_populate_sysroot_setscene: Succeeded
....
* Task Flags:
[dirs]: 任务运行前创建的目录;
[cleandirs]: 任务运行前创建,并且是空目录;
[noexec]: 不需要执行的任务;
[nostamp]: 不生成stamp文件,任务总是被重新执行;
[fakeroot]: 任务需要在fakeroot环境下执行;
[umask]: 任务运行时的umask
[depends/deptask/rdeptask/recdeptask/recrdeptask]: 依赖的任务必须完成才能执行此任务
本文忽略了任务的依赖及其他处理,仅讨论单个任务是如何被执行的。
* 简介:
任务是定义在bb文件中的python/shell函数,代表了软件包build过程中的一个步骤。Bitbake约定,任务名必须以’do_‘开
始,bitbake提供任务的分析和处理机制,具体的任务由bbclass/bbfile提供。
* 前情提要:
Bitbake以Server/UI的方式运行,Server端负责等待并执行命令,UI端负责提交命令并回显结果,二者通过一个双向命令管道
和一个状态队列进行交互。Server决定何时执行什么命令,而命令的具体执行由Cooker负责,这种机制通过回调函数实现。
以bzip2为例,执行以下命令时:
$ bitbake bzip2
1)Bitbake分析命令行得到:cmdline={'action': ['buildTargets', ['bzip2'], 'build'], 'msg': None};
2)UI调用server.runCommand(cmdline['action']),把命令传递给Server;
3)Server交给cooker处理,cooker.buildTargets()被执行,它把自己定义的方法buildTargetsIdle()注册到Server的_idlefunctions列表;
4)Server轮询并执行异步命令,控制权交还给buildTargetsIdle(),故事从这里开始了...
* 任务执行:
Bitbake中任务是一个对象,任务的表现形式是TaskData实例。TaskData可以添加,删除任务,处理任务的各种依赖,但是不能执行任务。
任务的执行依靠RunQueue实现, RunQueue是一个状态机,根据当前所处状态执行相应的操作,RunQueue初始化时状态为”runQueueSceneInit“。
从buildTargetsIdle()开始分析, '->'表示函数/方法的调用关系:
-> rq.execute_runqueue():
该方法执行runqueue队列中的任务,在初始状态下,它调用的是RunQueueExecuteScenequeue实例的execute()方法:
945 self.rqexe = RunQueueExecuteScenequeue(self)
948 retval = self.rqexe.execute()
-> RunQueueExecuteScenequeue.execute()
运行队列中的任务,每一个任务都不是单独存在的,若干任务构成了一条任务链,每个可执行任务最终要通过以下方式被执行:
1602 pid, pipein, pipeout = self.fork_off_task(fn, realtask, taskname)
-> RunQueueExecuteScenequeue.fork_off_task(): 这是一个Wrapper,下面才是真正的fork_off_task()
-> RunQueueExecute.fork_off_task():
先检查和设置任务执行的环境和相关变量,任务的Flag:[umask/fakeroot]就是在这里处理的; 执行任务调用如下方法:
1160 bb.build.exec_task
-> bb.build._exec_task(): 执行任务要比单独执行一个函数复杂一些,仍然需要处理任务相关的环境变量和数据;然后剥去任务的外衣,把它当做函数处理:
321 exec_func(task, localdata)
-> bb.build.exec_func(): 处理任务的其他Flags,根据任务类型(python/shell)分而治之;
170 if ispython:
171 exec_func_python(func, d, runfile, cwd=adir)
172 else:
173 exec_func_shell(func, d, runfile, cwd=adir)
a. -> bb.build.exec_func_python(): 如果任务是python函数:
200 utils.better_exec(comp, {"d": d}, code, bbfile)
-> bb.utils.better_exec(): python类型的任务最终由python内置函数exec执行:
343 exec(code, _context, context)
b. -> bb.build.exec_func_shell():如果任务是shell函数:
243 bb.process.run(cmd, shell=False, stdin=NULL, log=logfile)
-> bb.process.run():把函数转换成命令并返回命令的输出:
95 pipe = Popen(cmd, **options) # subprocess.Popen(), 有关Popen()详细使用请参考subprocess模块的help信息。
至此一个任务执行完毕。
* 总结:
Bitbake中用TakeDate,RunQueueData组织任务数据,而且任务处理过程中还涉及到了数据缓存,日志和事件信息的处理,它们
在BB中被抽象成了不同的类型和对象,希望以后能逐步分析,最终形成一个完整的BB对象类型系统说明。
* 参考:
$ bitbake bzip2 # 部分输出
NOTE: Resolving any missing task queue dependencies
NOTE: Preparing runqueue
NOTE: Executing SetScene Tasks
NOTE: Running setscene task 97 of 277 (/home/wenzong/sdb2/poky/meta/recipes-extended/bzip2/bzip2_1.0.6.bb:do_populate_sysroot_setscene)
NOTE: package bzip2-1.0.6-r3: task do_populate_sysroot_setscene: Started
NOTE: package bzip2-1.0.6-r3: task do_populate_sysroot_setscene: Succeeded
....
* Task Flags:
[dirs]: 任务运行前创建的目录;
[cleandirs]: 任务运行前创建,并且是空目录;
[noexec]: 不需要执行的任务;
[nostamp]: 不生成stamp文件,任务总是被重新执行;
[fakeroot]: 任务需要在fakeroot环境下执行;
[umask]: 任务运行时的umask
[depends/deptask/rdeptask/recdeptask/recrdeptask]: 依赖的任务必须完成才能执行此任务
相关文章推荐
- PHP计划任务:如何使用Linux的Crontab执行PHP脚本
- Android中如何实现后台执行定时任务
- Java如何判断线程池所有任务是否执行完毕
- 如何检查GATHER_STATS_JOB任务的执行情况
- 如何离线执行php任务
- crontab 执行定时任务如何控制前一个任务执行完后再启动下一个任务?
- PHP计划任务:如何使用Linux的Crontab执行PHP脚本
- php如何定时执行任务
- 在Java中如何设置一个定时任务,在每天的一个时间点自动执行一个特定的程序
- Java如何判断线程池所有任务是否执行完毕
- Linux下如何定时执行php脚本?Linux下如何设置定时任务?Crontab定时执行程序
- Linux下如何定时执行php脚本?Linux下如何设置定时任务?Crontab定时执行程序
- 安卓(Android)中如何优雅的 创建/执行 异步任务/回调(AsyncTask 、Thread、Job、CallBack、Handler) ?线程池(Executor)
- 集群环境下如何防止定时任务重复执行?
- CentOS7如何执行PHP定时任务详解
- 线程池 b399 概念 二、测试线程池如何执行任务
- asp.net如何定时执行任务
- 学习如何每隔一段时间定时重复执行任务
- 【转载】Linux下如何在特定时间执行特定任务
- 方法一 Java如何判断线程池所有任务是否执行完毕