码迷,mamicode.com
首页 > 系统相关 > 详细

《Linux系统编程手册》读书笔记——第2章基本概念

时间:2018-01-01 19:39:24      阅读:260      评论:0      收藏:0      [点我收藏+]

标签:字符串   打开文件   目的   目录   处理器   子进程   ksh   特权   signal   

操作系统的核心--内核

内核的职责

  1. 进程调度:Linux属于抢占式多任务操作系统,多个进程可同时驻留于内存,且每个进程都能获得对CPU的使用权。哪些进程获得对CPU的使用,以及每个进程能使用多长时间 ,都由内核进程调度程序决定。
  2. 内存管理:Linux采用了虚拟内在管理机制。
  3. 提供了文件系统
  4. 创建和终止进程:内核可将新程序载入内存,为其提供运行所需的资源。一旦程序执行完毕,内核还要确保释放其占用资源,以供后续程度重新使用。
  5. 设备的访问:内核既为程序访问设备提供了简化版的标准接口,同时还要仲裁多个进程对每一个设备的访问。
  6. 联网:内核以用户进程的名义收发网络消息(数据包)。该任务包括将网络数据包路由至目标系统。
  7. 提供系统调用应用编程接口(API):进程可利用内核入口点请求内核去执行各种任务。

内核态和用户态

? 在用户态下运行时,CPU只能访问被标记为用户空间的内存,试图访问属于内核空间的内存会引发硬件异常。当运行于核心态时,CPU既能访问用户空间内存,也能访问内核空间内存。

? 仅当处理器在核心态运行时,才能执行某些特定操作。如:执行宕机(halt)指令去关闭系统,访问内存管理硬件,以及设备I/O操作的初始化等。实现者们利用这一硬件设计,将操作系统置于内核空间。确保了用户进程既不能访问内核指令和数据结构,也无法执行不利于系统运行的操作。

shell

  • Bourne shell(sh)
  • C shell(csh)
  • Korn shell(ksh)
  • Bourne again shell(bash)

? 设计shell的目的不仅仅是用于人机交互,对shell脚本进行解释也是其用途之一。为实现这一目的,每款shell都内置有许多通常与编程语言相关的功能,其中包括变量、循环和条件语句、I/O命令以及函数等。

用户和组

用户

? 系统的每个用户都拥有唯一的登录名和与之相对应的整数型用户ID(UID)。系统密码文件/etc/passwd为每个用户都定义有一行记录,除了上述两项信息外,该记录还包含如下信息。

  • 组ID:用户所属第一个组的整数型组ID。
  • 主目录:用户登录后所居于的初始目录。
  • 登录shell:执行以解释用户命令的程序名称。

? 该记录还能以加密形式保存用户密码。然而,出于安全考虑,用户密码往往存储于单独的shadow密码文件中,仅供特权用户阅读。

? 每个用户都对应着系统组文件/etc/group中的一行记录,该记录包含如下信息。

  • 组名:(唯一的)组名称
  • 组ID(GID):与组相关的整数型ID。
  • 用户列表:隶属于该组的用户登录名列表(通过密码文件记录的group ID字段未能标识出的该组其他成员,也在此列),以逗号分隔。

超级用户

? 超级用户在系统中享有特权。超级用户账号的用户ID为0,通常登录名为root。

单根目录层级、目录、链接及文件

? 内核维护着一套单根目录结构,以放置系统的所有文件。这一目录层级的根基就是名为“/”的根目录。所有的文件和目录都是根目录的“子孙”。

路径和链接

? 每个目录至少包含两条记录:..和.,前者是指向目录自身的链接,后者是指向其上级目录——父目录的链接。对根目录而言,..是指向根目录自身的。

符号链接

? 分为硬链接和软链接。

文件的所有权和权限

? 每个文件都有一个与之相关的用户ID和组ID,分别定义文件的属主和性组。系统根据文件的所有权来判定用户对文件 的访问权限。

文件I/O模型

文件描述符

? I/O系统调用使用文件描述符——非负整数——来指代打开的文件。通常,由shell启动的进程会继承3个已打开的文件描述符:描述符0为标准输入,指代为进程提供输入的文件;描述符1为标准输出,指代供进程写入输出的文件;描述符2为标准错误,指代供进程写入错误消息或异常通告的文件。在stdio函数库中,这几种描述符分别与文件流stdin、stdout和stderr相对应。

stdio函数库

? C编程语言在执行文件I/O操作时,往往会调用C语言标准库的I/O函数。也将这样一组I/O函数称为stdio函数库,其中包括fopen()、fclose()、scanf()、printf()、fgets()、fputs()等。stdio函数位于I/O系统调用层(open()、close()、write()等)之上。

进程

进程的内存布局

? 逻辑上将一个进程划分为以下几部分(也称为段)

  • 文本:程序的指令。
  • 数据:程序使用的静态变量。
  • 堆:程序可从该区域动态分配额外内存。
  • 栈:随函数调用、返回而增减的一片内存,用于为局部变量和函数调用链接信息分配存储空间。

创建进程和执行程序

? 进程可使用系统调用fork()来创建一个新进程。调用 fork()的进程被称为父进程,新创建的进程则被称为子进程。内核通过对父进程的复制来创建 子进程。子进程从父进程处继承数据段、栈段以及堆段的副本后,可以修改这些内容,不会影响父进程的“原版”内容。(在内存中被标记为只读的程序文本段code则由父、子进程共享。)

? 然后,子进程要么去执行与父进程共享代码段中的另一组不同函数,或者,更为常见的情况是使用系统调用 execve()去加载并执行一个全新程序。execve()会销毁现有的文本段、数据段、栈段及堆段,并根据新程序的代码,创建新段来替换它们。

? 以execve()为基础,C语言库还提供了几个相关函数,接口虽然略不同,但功能全都相同。以上所有库函数的名称均以字符串“exec”打头,在函数间差异无关宏旨的场合,本书会用符号exec()作为这些库函数的统称。不过,实际上根本不存在名为exec()的库函数。

进程ID和父进程ID

? 每一进程都有一个唯一的整数型进程标识符(PID)。每一进程还具有一个父进程标识符(PPID)属性,用以标识请求内核创建自己的进程。

init进程

? 系统引导时,内核会创建一个名为init的特殊进程,即“所有进程之父”,该进程的相应程序文件为/sbin/init。系统的所有进程不是由init(使用fork())“亲自”创建,就是由其后代进程创建。init进程的进程号总为1,且总是以超级用户权限运行。

守护进程

? 守护进程指的是具有特殊用途的进程,系统创建和处理此类进程的方式与其他进程相同,但以下特征是其所独有的:

  • “长生不老”。守护进程通常在系统引导时启动,直至系统关闭前,会一直在。
  • 守护进程在后台运行,且无控制终端供其读取或写入数据。

守护进程中的例子有syslogd(在系统日志中记录消息)和httpd(利用HTTP分发Web页面)。

环境列表

? 每个进程都有一份环境列表,即在进程用户空间内存中维护的一组环境变量。这份列表的每一元素都由一个名称及其相关值组成。由fork()创建的新进程,会继承父进程的环境副本。这也为父子进程间通信提供了一种机制。当进程调用 exec()替换当前正在运行的程序时,新程序要么继承老程序的环境,要么在exec()调用的参数中指定新环境并加以接收。

? 在绝大多数shell中,可使用export命令来创建环境变量(C shell使用setenv命令),

? 如$ export MYVAR=‘Hello world‘

? C语言程序可使用外部变量(char **environ)来访问环境,而库函数也允许进程去获取或修改自己的环境中的值。

? 环境变量的用途多种多样。例如,shell定义并使用了一系列变量,供shell执行的脚本和程序访问。其中包括:变量HOME(明确定义了用户登录目录的路径名)、变量PATH(指明了用户输入命令后,shell查找与之相应程序时所搜索的目录列表)。

资源限制

? 每个进程都会消耗诸如打开文件、内存以及CPU时间 之类的资源。使用系统调用 setrlimit(),进程可为自己消耗的各类资源设定一个上限。此类资源限制的每一项均有两个相关值:软限制限制了进程可以消耗的资源总量,硬限制软限制的调整上限。非特权进程在针对资源调整软限制值时,可将其设置为0到相应硬限制值之间的任意值,但硬 限制值则只能调低,不能调高。

? 由fork()创建的新进程,会继承其父进程对资源限制的设置。

? 使用ulimit命令(在C shell中为limit)可调整shell的资源限制。shell为执行命令所创建的子进程会继承上述资源设置。

进程间通信及同步

Linux提供了丰富的进程间通信(IPC)机制。

  • 信号(signal),用来表示事件的发生。
  • 管道和FIFO,用于在进程间传递数据。
  • 套接字,借同一台主机或是联网的不同主机上所运行的进程之间传递数据。
  • 文件锁定,为防止其他进程读取或更新文件内容,允许某进程对文件的部分区域加以锁定。
  • 消息队列,用于在进程间交换消息(数据包)。
  • 信号量,用来同步进程动作。
  • 共享内存,允许两个及以上进程共享一块内存。当某进程改变了共享内存的内容时,其他所有进程会立即了解到这一变化。

线程

? 每个进程都可执行多个线程。可将线程想象为共享同一虚拟内存及一干其他属性的进程。每个线程都会执行相同的程序代码,共享同一数据区域和堆。可是,每个线程都拥有属于自己的栈,用来装载本地变量和函数调用 链接信息。

? 线程之间可通过共享的全局变量进行通信。借助于线程API所提供的条件变量和互斥机制,进程所属的线程之间得以相互通信并同步行为——尤其是在对共享变量的使用方面。此外,利用IPC和同步机制,线程间也能彼此通信。

? 线程的主要优点在于协同线程之间的数据共享更为容易,而且就某些算法而论,以多线程来实现比之以多进程实现要更加自然。再者,显而易见,多线程应用能从多处理器硬件的并行处理中获益匪浅。

/proc文件系统

? Linux提供了/proc文件系统,由一组目录和文件组成,装配(mount)于/proc目录下。

? /proc文件系统是一种虚拟文件系统,以文件系统目录和文件形式,提供了一个指向内核数据结构的接口。这为查看和改变各种系统属性开启了方便之门。此外,还能通过一组以/proc/PID形式命名的目录(PID即进程ID)查看系统中运行各进程的相关信息。

? 通常,/proc目录下的文件内容都采取人类可读 的文件形式,shell脚本也能对其进行解析。程序可以 打开、读取和写入/proc目录下的既定文件。大多数情况下,只有特权级进程才能修改/proc目录下的文件内容。

《Linux系统编程手册》读书笔记——第2章基本概念

标签:字符串   打开文件   目的   目录   处理器   子进程   ksh   特权   signal   

原文地址:https://www.cnblogs.com/zslhg903/p/8167976.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!