设为首页 加入收藏

TOP

4.1.4 操作系统的核心服务
2013-10-07 12:58:15 来源: 作者: 【 】 浏览:61
Tags:4.1.4 操作系统 核心 服务

4.1.4  操作系统的核心服务

操作系统的核心服务可以分为:

进程管理

内存管理

文件系统管理

I/O管理

进程间通信管理器(Interprocess Communication Manager)

表4-1简要描述了这些核心服务。

表4-1

操作系统核心服务< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

   

进程管理

管理进程的行为和资源,包括进程执

行、资源分配与保护、同步

内存管理

管理进程的内存分配,包括如何将内存

分配给进程以及当内存完全被利用时如何处理

文件系统管理

在存储设备上组织收集的数据,并

提供访问这些设备上的数据的接口

I/O管理

管理来自硬件设备的输入和输出请求

进程间通信管理器

管理进程间通信


尽管这些服务与所有应用程序开发人员都有关,但对于多线程或多处理应用程序的开发人员则更为明显。这是因为类似于进程调度或进程间通信等功能对于顺序处理应用程序往往是透明的。例如,在一个顺序处理应用程序中,操作系统只需要加载开发人员的程序。开发人员通常不关心操作系统如何将应用程序划分为进程、进程如何被调度、被调度的进程优先级如何,不需要担心共享内存违规,只要操作系统给应用程序足够的内存,则万事大吉。因为在顺序处理的应用程序中不存在并发执行的子任务,所以任务间通信和同步不构成问题。对于多处理和多线程应用程序,状况则完全不同。在第3章中,我们已经讨论了开发人员在开发这种类型的应用程序时所面临的挑战。根据该章讲述的内容,一些特别的、与操作系统服务相关的挑战是:

软件被分解为需要同时执行的指令或任务集

并行执行的两个或多个任务之间的通信

两个或多个指令或任务并发访问或更新数据

确定并发执行任务片之间的关系

当任务和资源之间存在多对一比例时控制资源竞争

确定需要并行执行的最优的或可接受的单元数目

记录并沟通包含多处理和多线程的软件设计

创建测试环境来仿真并行处理需求和条件

重建软件异常或错误以消除软件缺陷

为涉及多线程和多处理的组件实现操作系统和编译器接口

一旦软件设计过程确定应用程序最好分成两个或多个并发执行的任务,则操作系统的透明性立刻会成为问题。这是因为操作系统不具备自动任务分解的能力,但是需要由操作系统来负责创建和管理进程与线程。最终,并发执行的任务必须映射到进程、线程或两者的结合。当前的操作系统和编译器还不能够自动完成这种映射。必须有人在应用程序的并发需求和支持多处理和多线程的操作系统API和SPI之间担当联络官。如果您在使用来自图4-1的级别3和级别4中的技术和工具,那么操作系统的作用大部分是透明的(但明确存在)。如果您在图4-1中所示的级别1或级别2上进行工作,那么需要具备操作系统API和SPI的特定知识。

为了更仔细地观察操作系统在开发必须并发执行任务中的作用,您可以查看一个已经被分解为4个同时执行的任务的应用程序。使用当前的现代操作系统的C++(www.cppentry.com)开发人员可以有3种基本选择来实现这些任务。任务可以被实现为:

进程

线程

进程和线程的组合

图4-2显示了4-任务应用程序的基本分解选择的框图。

 
(点击查看大图)图4-2

在图4-2的情形1中,应用程序被分为4个任务。这4个任务是通过3个操作系统进程来实现的。图4-2显示了应用程序将部署在4核计算机上。4个任务通过3个进程来实现,意味着任务中的3个有可能同时在3个不同的处理器上实际执行,或者在任意数目的处理器上采用多道程序设计。如果采用多道程序设计,则操作系统在进程间快速切换,这样允许多个进程在指定的时间间隔内并发完成工作。尽管在某个时刻只有一个进程实际使用处理器,但是进程之间的切换速度非常快,一秒钟之内会有两个或多个进程在处理器上执行工作。尽管在图4-2中是4核计算机,我们实际上只能够同时执行3个任务。这是因为4个用户任务已经被映射到3个进程。操作系统只能够将进程或内核线程(轻量级进程)调度到处理器上执行。它不能够调度逻辑任务,除非它们已经被映射到进程或内核线程。即使4个内核都空闲,但是在情形1中,只有3个内核会被应用程序同时使用。任务3和任务4共享一个进程。情形1使用多处理,因为它通过将其任务指派给操作系统进程来利用操作系统的多处理器。系统指派进程到任意空闲内核。所以,如果应用程序被划分为进程,它可以利用系统能够并行运行的进程数目与处理器数目相同的事实。

1. 如何实现从任务到进程的转换

为了将用户任务映射到系统进程,您需要使用操作系统API。在本例中,使用的是posix_spawn( )函数。函数posix_spawn( )用于创建一个新的操作系统进程。posix_spawn( )是操作系统的进程管理API的一部分。任何通过posix_spawn( )关联到进程的任务可以被操作系统调度,与其他进程并行运行。注意在情形1中,Task 1需要与Task 3和Task 4进行单向通信,而Task 3和Task 4需要与Task 2进行双向通信。这带来了关于同操作系统交互的另一个问题,即如何在并发执行的进程之间传递信息?有很多方法可以完成上述工作,但是所有这些方法都要求与操作系统API进行交互。在本例中,您可以使用POSIX消息队列。表4-2包含了POSIX消息队列函数的简要描述。它们是允许并发执行的进程传递信息的POSIX API函数的实例。

表4-2

POSIX消息队列函数

   

mq_open( )

通过消息队列描述符,建立进程和消息队列之间的联系

mq_close( )

解除消息队列描述符与它对应的消息队列之间的关联

mq_send( )

将消息加入到指定的消息队列

mq_receive( )

从指定消息队列中接受优先级最高且时间最久的消息

mq_notify( )

记录当消息到达与指定消息队列描述

符关联的空的消息队列时需要通报的调用进程

mq_getattr( )

获得消息队列的属性的状态信息以及与

消息队列描述符关联的消息队列描述

mq_setattr( )

设置消息队列的状态信息和属性


2. 使用线程方法

在图4-2中的情形1中的分解中,将进程作为了分解单元。情形2将线程作为了分解单元。与情形1中应用程序产生3个进程不同,在情形2中,应用程序只有一个进程。然而,这个进程被分成3个可以并发执行的用户线程。在这个场景中,4个并发任务的需求通过使用3个线程来实现。线程A、B和C均被指派任务,意味着4个任务必须在3个线程之间进行分布。值得注意的是,情形2只有两个内核线程。由于操作系统为处理器调度进程或调度内核线程,所以情形2中唯一的进程可以被调度到一个处理器,或者两个内核线程可以被调度到单独的处理器。这样,如果所有4个内核都是空闲的,则最多两个任务可以被同时执行。

在情形2中,线程A、B、C是用户线程。用户线程在某些情况下可以绑定到内核线程,或者与内核线程解除绑定(如本书稍后将会讨论的那样)。在情形2中,用户线程在真正被执行之前必须与内核线程关联。这样,在我们的线程方法中,可将软件任务映射到用户线程,然后用户线程被映射到内核线程或轻量级进程(lightweight processes,lwp)。

注意:

第6章将解释用户线程和内核线程之间的区别。

3. 如何实现从任务到线程的转换

pthread_create( )操作系统API用于将软件任务与线程进行关联。这个函数还被归入操作系统负责进行进程管理的部分。我们将在第6章详细介绍POSIX线程API。除非用户是使用来自级别3或级别4(见图4-1)的工具和技术进行工作,否则应将软件任务和线程关联起来,并要求理解如何使用POSIX线程API。注意在图4-2中,在使用线程方法进行分解时,任务的通信需求不要求特殊的操作系统干涉。这是因为线程共享相同的地址空间,因此可以共享进程的数据段中保存的数据结构。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇4.2 分解以及操作系统的任务 下一篇6.2.3 实体间的通信

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: