《OS X与iOS内核编程》试读:1.6 调度

在计算机系统中,另一种争用激烈的资源是CPU。执行每个进程都需要访问CPU,但通常一些想要访问CPU的进程比系统上的CPU内核更活跃。因此操作系统必须在运行的进程之间共享CPU内核,保证每个进程都可以正常访问CPU,从而顺利执行。 我们已经知道,进程彼此独立运行,都有各自的地址空间,以防止一个进程影响其他进程的行为。但在许多应用程序中,让两个独立执行的路径同时运行,而且不受每个路径必须在各自地址空间中运行的限制,这样做非常有用。这一执行单元被称为“线程”。多个线程都执行同一程序的代码,并在同一进程中运行(从而共享相同的地址空间),但却彼此独立。 对于操作系统来说,线程是调度的基本单位;当操作系统调度程序考虑接下来在CPU上调度什么时,只需查看系统上的活动线程。进程如若执行,至少要包含一个线程;一个新进程开始运行时,操作系统会自动为其创建初始线程。 调度器有两个作用:防止CPU闲置,否则会浪费宝贵的硬件资源;让所有线程公平地访问CPU,防止因单个线程独占CPU而导致其他线程无法运行。为此,一个线程会在可用的CPU内核上调度执行,直至以下任一事件发生。 过了一定时间(称之为时间量子)后,那时原线程将被操作系统抢占,调度执行另一个线程。在Mac OS X上,默认的时间量子是10毫秒。 线程在等待操作(如从磁盘读取数据或另一个线程返回结果)完成时,将不能执行。在这种情况下,调度器会让另一个线程在CPU上运行,从而阻塞原来的线程。这可以防止CPU在一个线程没有工作时处于闲置状态,从而最大限度地提高CPU在执行代码上花费的时间。线程还可以调用sleep()函数,自动放弃CPU时间,这会使当前线程的执行延迟一段时间。 为一个应用程序添加多个线程的一个原因是,使其可以在多个CPU内核中并发执行,从而能够将复杂的操作划分为多个同步运行的小步骤,从而加速应用程序的执行。即使在单核计算机上,多线程也有其优点。通过在活动线程间快速切换,调度器会让用户产生所有线程同时运行的错觉。即使一个线程被阻塞或进入了死循环,也不会影响其他线程的响应速度。这样,就可以将耗时的任务移到后台线程,让应用程序的其他部分自由地响应用户交互。 对于与硬件交互的应用程序,一种常见的设计是将访问硬件的代码放到其自身的线程中。软件代码等待硬件响应时常常进入阻塞状态;通过移除主程序线程中的这些代码,当程序需要等待硬件响应时,就不会对其用户界面产生影响。 另一种使用线程的常见情况是,保证软件以最小的延迟来响应硬件事件。应用程序在收到硬件通知前可以创建一个阻塞线程,然后可以使用后面几章介绍的技术与该线程通信。线程阻塞时,调度器不需要给它访问CPU的机会,因此线程的存在并不影响系统的性能。但在硬件发出事件通知之后,线程会变为非阻塞状态并在CPU上调度执行,并且可以自由执行任何需要的操作,从而响应硬件。

>OS X与iOS内核编程

OS X与iOS内核编程
作者: [澳] Ole Henry Halvorsen, [澳] Douglas Clarke
原作名: OS X and iOS kernel programming
isbn: 7115318247
页数: 400
译者: 贾 伟
定价: 89.00
出版社: 人民邮电出版社
装帧: 平装
出版年: 2013-6
书名: OS X与iOS内核编程