查看“Loading a Process”的源代码
←
Loading a Process
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
加载和启动进程可以通过多种方式完成。 == 载入器功能 == 在[http://forum.osdev.org/viewtopic.php?p=112592#p112592 这篇文章]Brendan描述了创建的进程执行加载功能的方式,该功能可以将可执行文件加载到其地址空间中。 只有当进程获得其时间片时,此加载程序函数才处于活动状态。 这样,生成新进程的进程就不会被阻止。 *创建一个新的页面目录(映射到内核空间); *将内核页面表复制到新的页面目录中; *设置计划程序数据(线程优先级等)并将初始EIP设置为“启动进程”内核函数; *(可选)等待或阻止,直到新线程设置某种状态以返回; * 返回给调用者。 在此之后,我在内核空间中运行了一个新的线程/进程。 当调度器给它一个时间片时,内核设置“用户空间”(加载一个可执行文件等),然后“返回”到CPL=3。 不过,所有这些都是在新地址空间内发生的,因此不存在分页等问题。 对于错误处理,对于我的操作系统,一切都是异步的——生成线程不会阻止从生成线程等待状态。 在内核“返回”到新进程/线程之前,它会向第一个线程发送一条状态/错误消息。 这意味着“spawnThread()”函数可能会返回“OK”,之后可能会向你发送一个错误(例如“failed to load executable file”)。 对于同步操作系统,“spawnProcess()”函数将阻塞,直到返回完整状态。 理论上,这对应用程序程序员来说更容易使用,但对性能来说更糟。 例如,用户界面可能会锁定几秒钟,因为系统挣计划生成一个进程(例如,新进程的可执行文件恰好是慢速文件系统上的一个大文件)。 为了避免这个问题,应用程序程序员可能希望生成一个新线程来生成新进程;但这使得它比异步函数更难使用,开销更大,而且大多数应用程序程序员不会这么做(这要么太麻烦,要么他们根本没有意识到问题的存在)。 == 进程管理器== 进程管理器用于加载Messiah Andrw[http://forum.osdev.org/viewtopic.php?p=112605#p112605 文章]中描述的可执行文件。 进程管理器在自己的线程中运行。 通常这个线程处于休眠状态,但是如果一个作业被添加到进程管理器的队列(“生成进程”——这就是它现在使用的全部功能),进程管理器的线程处于休眠状态。 发送请求的进程通常会休眠,直到进程管理器完成其工作 - 但在多线程应用程序中,在加载进程的同时也可以执行其他操作。 当我的调度程序切换到这些特殊的内核线程(进程管理器、vfs管理器等)时,它实际上会切换到它正在工作的进程的内存上下文。 这样,真正大的请求(例如,从文件中加载20MB)实际上是在一个单独的内核线程中处理的,数据被加载到进程的地址空间中,从而允许进程和所有其他进程继续做它想做的事情。 这确实会对性能造成(相当轻微的)损失。 例如,要将程序加载到内存中,系统必须执行以下操作: * 父程序请求加载程序。 * - 跳到内核领域 - * 内核将请求添加到进程管理器的队列中。唤醒进程管理器。 * - 跳转到用户领域- * 父程序请求进入睡眠状态。 * - 跳转到内核领域 - * 从“awake”列表中删除程序。 *-等待上下文切换到进程管理器- * 设置新进程的内存。从VFS管理器请求文件。唤醒VFS管理器。将进程管理器转为睡眠状态。 循环开始: *- 等待上下文切换到VFS管理器 - *从磁盘驱动程序请求部分文件。 唤醒磁盘驱动程序。 让VFS进入睡眠状态。(请求被分成128kb的块,因此可以同时进行多个读/写操作)。 * - 等待上下文切换到磁盘驱动程序- * 从磁盘加载部分文件。唤醒VFS。 如果未完全加载,则返回循环的开头(VFS将只请求文件的一部分,例如,先请求ELF头,然后请求程序头,然后请求数据等)。 * 唤醒进程管理器。 * - 等待上下文切换到进程管理器- * 将新进程添加到调度算法中。 唤醒父进程。 如果没有其他东西要排队,将进程管理器发送到睡眠状态。 正如你所看到的,需要做很多工作。 这些特殊线程并不是内核的一部分,它们也不存在于它们自己的地址中,它们只是走到其他进程,然后说“怎么了,我能跟你相处一段吗?” ==延迟加载== 当你的操作系统支持从任何文件(而不仅仅是交换文件)交换页面时,你可以创建一个地址空间,将页面标记为不存在,并映射到磁盘上的可执行文件。 这样,当新进程开始执行时,内存管理器将自动从可执行文件中交换所需的页面。 它只加载此时需要的页面,因此在启动时需要更少的内存。 ==准入调度器(Admission Scheduler)== 一些操作系统使用长期调度器(long-term scheduler)或准入调度器(admission scheduler)来控制特定进程的启动时间。 它主要用于实时操作系统来控制系统的负载。 这个想法类似于前面[[Loading a Process#进程管理器|进程管理器]]方法。 如果你曾经打算支持实时调度,这是一条路要走。 或者哪怕你的操作系统最初只是一个简单的桌面操作系统,你这样做也可以对准入调度器进行编码,以自动加载其队列中的任何可执行文件。 ==参考文献== ===文章=== *[[Context Switching|上下文切换]] *[[Processes and Threads|进程和线程]] === 论坛主题 === * [http://forum.osdev.org/viewtopic.php?f=1&t=15622 Loading processes in (new) virtual address space] ===外部链接=== * [[Wikipedia:Scheduling (computing)#Long-term_Scheduler|Admission Scheduler]] [[Category:Processes and Threads]]
返回至“
Loading a Process
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
变体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息