译:深入Linux内核架构(第一章)1.3—1.31—1.32

译:深入Linux内核架构(第一章)

注:选择性翻译原文。

1.3内核原理

本章节为大量的内核原理提供简要的概述,以及简要描述一下我们将会在下面章节中详述的大纲。尽管很庞大,Linux仍然构造得很出色。然而,单个元素之间的互相影响是不可避免的。他们分享数据结构和(性能的缘故)通过各类函数互相协调,也是在严格隔离的系统中所必须的。图1-1是一个粗略的初期的层次概括图,囊括着Linux系统,和一些内核关键的子系统。注意,在下图中没有给出单个子系统交互在各种各样的其他方式。


1.3.1进程、任务切换、调度

应用程序,服务器,以及其他一些在Unix下运行的程序,传统上统称为进程。每个进程的地址空间都由CPU分配虚拟内存。进程私有地址空间是完全独立的,以致进程之间完全不知道彼此间的工作,除非进程间取得联系,否则似乎是系统中唯一一个运行的进程一样。如果进程想通信交换数据,则必须使用特殊的内核机制。(进程间通信机制等)

因为Linux是一个多任务系统,它支持几个并发进程。由于在同一时间,只有多CPU系统才能同时运行对应的几个进程,因此内核以很短的时间在不同进程间切换(不被用户注意),让人觉得几个进程同时运行。这里,产生两个问题区:

1、在CPU的帮助下,内核负责的技术细节的任务切换。每个单独的进程必须被引导为觉得CPU总是可用的是通过在CPU资源被回收前保存所有相关元素的状态来实现的,并且进程是处于空闲状态。当进程被从新激活,就会恢复保存的状态。进程间的切换称为任务切换。

2、内核还必须决定如何在现有的进程间共享CPU时间。重要的进程将分配更多的CPU时间(时间片),分量那么重的线程分配的时间片相对较少。决定哪些进程运行多长时间被称为调度。

1.3.2Unix进程

Linux采取分级方案,每个进程取决于他的父进程。内核启动init进程作为第一个进程,负责进一步的系统初始化操作和显示登录提示或(今天广泛使用)显示一个图形登录界面。因此init所有进程获得root权限的来源,或多或少,如pstree所示。Init是树形结构的最高点,其分支向下延伸,扩展。

wolfgang@meitner>  pstree

init-+-acpid

|-bonobo-activati

|-cron

|-cupsd

|-2*[dbus-daemon]

|-dbus-launch

|-dcopserver

|-dhcpcd

|-esd

|-eth1

|-events/0

|-gam_server

|-gconfd-2

|-gdm---gdm-+-X

-startkde-+-kwrapper

-ssh-agent

|-gnome-vfs-daemo

|-gpg-agent

|-hald-addon-acpi

|-kaccess

|-kded

|-kdeinit-+-amarokapp---2*[amarokapp]

|-evolution-alarm

|-kinternet

|-kio_file

|-klauncher

||-konqueror

||-konsole---bash-+-pstree

|-xemacs

| |-kwin

|  |-nautilus

|  ‘-netapplet

|-kdesktop

|-kgpg

|-khelper

|-kicker

|-klogd

|-kmix

|-knotify

|-kpowersave

|-kscd

|-ksmserver

|-ksoftirqd/0

|-kswapd0

|-kthread-+-aio/0

|  |-ata/0

|  |-kacpid

|  |-kblockd/0

|-kgameportd

|-khubd

-kseriod

|-2*[pdflush]

|  ‘-reiserfs/0

这棵树结构是如何随着新进程的产生而扩展并紧密相连的。对于这个目的,Unix用了两个机制:forkexec

1、fork——生成一个精确复制于当前进程的进程,唯一不同于父进程的只有在它的PID(过程识别)。在系统调被执行后,系统中有两个进程,两个进程执行系统的操作。满足初始化进程的内存会被复制出来,至少是在进的角度。Linux使用一个著名的技术:copy on write,通过推迟复制操作直到要么父或子进程写一页上来使操更加高效,对于父子进程,只读权限可以满足访问同一页面。

一个适用用fork的场合是,当一个用户打开第二个浏览器窗口。如果相应的选项被选中, 浏览器执行一个fork复制它的代码,然后开始适当的行动在子进程中建立一个新的窗口。

2exec——加载一个新的程序到一个现有的内容,然后执行它。旧进程保留内存页面被 冲洗掉,里面的内容 新进程数据代替。执行新的进程。

线程

进程并非内核所支持的程序运行的唯一形式。除重量级进程外,经典Unix进程还有另外一个名字——线程,一些参考资料也叫轻量级进程。他们存在有一段时间了,从本质上来说,一个进程可能包括几个线程,其都能通共享相同的数据和资源,但在程序代码中扮演不同的角色。线程的概念被完全融入许多现代语言,如java。简单来说,一个进程可以看做为一个运行的程序,而一个线程是一个程序函数或程序,运行在平行于主程序的位置上。这是否有意,例如,当Web浏览器需要并发地加载几个图片。通常,浏览器将不得不执行几个fork和exec调用来形成并发事件。这些将负责加载图片和制作数据,以便主程序能通过一些通讯机制来接受到。线程使  这种情况更容易处理。浏览器定义了一个常规加载图片,和进程以多态形式开始运行(每个都有不同的参数)。因为线程和主程序共享相同的地址空间,接收到的数据自动驻留在主程序里面。因此不需要任何通讯手段,除了防止线程同时访问相同没存而造成冲突。如图1-2,阐述了进程与线程间的不同。

Linux提供了克隆的方法来生成线程。这工作在一个简单的fork原理,但使能一个精确的检查,其组成资源与父进程共享,是相对于线程独立产生的。这个细化分布的资源扩展了经典线程  概念和允许一个或多或少的线程和进程之间的连续过渡。

命名空间

2.6内核的发展期间,对名称空间的支持被集成到众多的子系统。这允许系统中不同的进程有不同的形式。传统上,Linux使用许多全局的进程标识符:每个进程在系统配备一个唯一的标识符(ID),这个ID可以受用于用户(或其他进程)来引用进程——通过发送一个信号。跟命名空间比起来,以前的全局资源有显不同:每个命名空间可以包含一组特定的PID或者可以提供文件系统的不同视图。当文件系统挂载到一个名称空间就不能传递到另一个去了。

命名空间很好用,例如,他们是有利于托管服务提供商:而不是为每个客户建立一个物理机,他们可以用容器与名称空间来实现创建多个视图的系统,其中每一个似乎都是来自内部容器而非其他容器的完整的Linux安装。他们是分开的,以及跟其他的隔离开来。每个实例看起来像一个运行Linux的机器,但事实上,许多这样的实例可以同时作用在一个物理机器上。这有助于更有效地使用资源。相比之下,与如KVM一样完全虚拟化解决方案相比,只需要一个运行在机器上的内核来负责管理所有容器。

内核中不是所有的部分都识到名称空间,我将讨论当我们分析各种子系统的时候,会讨论子系统对命名空间的支持度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值