diff --git a/source/chapter5/4scheduling.rst b/source/chapter5/4scheduling.rst index e58b2f40..0b2a5e7c 100644 --- a/source/chapter5/4scheduling.rst +++ b/source/chapter5/4scheduling.rst @@ -76,17 +76,17 @@ 性能指标 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -我们还需给出性能指标,用于衡量,比较和评价不同的调度策略。对于批处理系统中的一般应用而言,可以只有一个性能指标:周转时间(turn around time),即进程完成时间与进程到达时间的差值: +我们还需给出性能指标,用于衡量,比较和评价不同的调度策略。对于批处理系统中的一般应用而言,可以只有一个性能指标:周转时间(turn around),即进程完成时间(completion)与进程到达时间(arrival)的差值: .. math:: - T_{周转时间} = T_{完成时间} − T_{到达时间} + T_{\text{turn around}} = T_{\text{completion}} − T_{\text{arrival}} -由于前提条件1 明确指出所有进程在同一时间到达,那么 :math:`T_{到达时间} = 0` ,因此 :math:`T_{周转时间} = T_{完成时间}` 。除了总的周转时间,我们还需要关注平均周转时间这样的统计值: +由于前提条件1 明确指出所有进程在同一时间到达,那么 :math:`T_{\text{arrival}} = 0` ,因此 :math:`T_{\text{turn around}} = T_{\text{completion}}` 。除了总的周转时间,我们还需要关注平均周转时间(average turnaround)这样的统计值: .. math:: - T_{平均周转时间} = T_{周转时间} / 就绪进程个数 + T_{\text{average turnaround}} = T_{\text{turn around}} / \text{number of ready processes} 对于单个进程而言,平均周转时间是一个更值得关注的性能指标。 @@ -189,13 +189,13 @@ .. math:: - T_{响应时间} = T_{首次执行} - T_{到达时间} + T_{\text{response time}} = T_{\text{first execution}} - T_{\text{arrival}} -而对应的平均响应时间是: +而对应的平均响应时间(average response time)是: .. math:: - T_{平均响应时间} = T_{响应时间} / 就绪进程个数 + T_{\text{average response time}} = T_{\text{response time}} / \text{number of ready processes} 例如,操作系统采用SJF调度策略(不支持抢占进程),有两个进程,PA在时间0到达,执行时间为100, PB在时间20到达,执行时间为20,那么PA的响应时间为0,PB为80,平均响应时间为 40 。 diff --git a/source/chapter8/4condition-variable.rst b/source/chapter8/4condition-variable.rst index ab43f238..225918d1 100644 --- a/source/chapter8/4condition-variable.rst +++ b/source/chapter8/4condition-variable.rst @@ -225,9 +225,9 @@ 由于互斥锁的存在, ``signal`` 操作也不只是简单的唤醒操作。当线程 :math:`T_1` 在执行过程(位于管程过程中)中发现某条件满足准备唤醒线程 :math:`T_2` 的时候,如果直接让线程 :math:`T_2` 继续执行(也位于管程过程中),就会违背管程过程的互斥访问要求。因此,问题的关键是,在 :math:`T_1` 唤醒 :math:`T_2` 的时候, :math:`T_1` 如何处理它正持有的锁。具体来说,根据相关线程的优先级顺序,唤醒操作有这几种语义: -- Hoare 语义:优先级 :math:`T_2>T_1>其他线程` 。也就是说,当 :math:`T_1` 发现条件满足之后,立即通过 ``signal`` 唤醒 :math:`T_2` 并 **将锁转交** 给 :math:`T_2` ,这样 :math:`T_2` 就能立即继续执行,而 :math:`T_1` 则暂停执行并进入一个 *紧急等待队列* 。当 :math:`T_2` 退出管程过程后会将锁交回给紧急等待队列中的 :math:`T_1` ,从而 :math:`T_1` 可以继续执行。 -- Hansen 语义:优先级 :math:`T_1>T_2>其他线程` 。即 :math:`T_1` 发现条件满足之后,先继续执行,直到退出管程之前再使用 ``signal`` 唤醒并 **将锁转交** 给 :math:`T_2` ,于是 :math:`T_2` 可以继续执行。注意在 Hansen 语义下, ``signal`` 必须位于管程过程末尾。 -- Mesa 语义:优先级 :math:`T_1>T_2=其他线程` 。即 :math:`T_1` 发现条件满足之后,就可以使用 ``signal`` 唤醒 :math:`T_2` ,但是并 **不会将锁转交** 给 :math:`T_2` 。这意味着在 :math:`T_1` 退出管程过程释放锁之后, :math:`T_2` 还需要和其他线程竞争,直到抢到锁之后才能继续执行。 +- Hoare 语义:优先级 :math:`T_2>T_1>\text{other processes}` 。也就是说,当 :math:`T_1` 发现条件满足之后,立即通过 ``signal`` 唤醒 :math:`T_2` 并 **将锁转交** 给 :math:`T_2` ,这样 :math:`T_2` 就能立即继续执行,而 :math:`T_1` 则暂停执行并进入一个 *紧急等待队列* 。当 :math:`T_2` 退出管程过程后会将锁交回给紧急等待队列中的 :math:`T_1` ,从而 :math:`T_1` 可以继续执行。 +- Hansen 语义:优先级 :math:`T_1>T_2>\text{other processes}` 。即 :math:`T_1` 发现条件满足之后,先继续执行,直到退出管程之前再使用 ``signal`` 唤醒并 **将锁转交** 给 :math:`T_2` ,于是 :math:`T_2` 可以继续执行。注意在 Hansen 语义下, ``signal`` 必须位于管程过程末尾。 +- Mesa 语义:优先级 :math:`T_1>T_2=\text{other processes}` 。即 :math:`T_1` 发现条件满足之后,就可以使用 ``signal`` 唤醒 :math:`T_2` ,但是并 **不会将锁转交** 给 :math:`T_2` 。这意味着在 :math:`T_1` 退出管程过程释放锁之后, :math:`T_2` 还需要和其他线程竞争,直到抢到锁之后才能继续执行。 这些优先级顺序如下图所示: