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

操作系统的核心--内核

内核的职责

  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目录下的文件内容。

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

时间: 2024-08-08 13:45:17

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

《Unix环境高级编程》读书笔记 第3章-文件I/O

1. 引言 Unix系统的大多数文件I/O只需用到5个函数:open.read.write.lseek以及close 本章描述的函数经常被称为不带缓冲的I/O.术语不带缓冲指的是在用户的进程中对其不会自动缓冲,每个read和write都调用内核中的一个系统调用.但是,所有磁盘I/O都要经过内核的块缓存区(也称为内核的缓冲区高速缓存).唯一例外的是对原始磁盘设备的I/O. 2. 文件描述符 对于内核而言,所有打开的文件都通过文件描述符引用.文件描述符是一个非负整数,其变化范围是0~OPEN_MAX

《Unix环境高级编程》读书笔记 第7章-进程环境

1. main函数 int main( int argc, char *argv[] ); argc是命令行参数的数目,包括程序名在内 argv是指向参数的各个指针所构成的数组,即指针数组 当内核执行C程序时(使用exec函数),在调用main前先调用一个特殊的启动例程.可执行程序文件将此启动例程指定为程序的起始地址——这是由连接器设置的,而连接器则是由C编译器调用.启动例程从内核取得命令行参数和环境变量值,然后按上述方式调用main函数做好安排. 2. 进程终止 有8种方式使进程终止,其中5种

TLPI(liunx/unix系统编程手册)笔记(三) 文件IO:通用的IO模型

读下来总的就是介绍了四个IO的API--open,read,write,close. 大家都是知道的,everything is file,在linux系统里面一切都是看作文件来操作的,学习linux就得先学好文件IO,也可以看见TLPI这本书的介绍完一些概念之后就开始介绍文件IO了. IO,大概的分为磁盘文件IO,buffering(缓冲)IO.貌似缓冲的水很深,之后会写博客. ------------------------------------ (1)文件描述符. 在进行IO操作之前,总

TLPI(liunx/unix系统编程手册)笔记(四) 深入探究文件I/O

本章的重点我想就是原子操作,避免在几个进程在打开同一文件的时候造成的错误,了解一下时间片的概念会对本章有所帮助. (1)独占方式打开文件.(open     <-O_CREAT) 知道,open,可以创建文件并返回fd.当我们的进程运行到open这个函数时间片到了,另一个进程也对这个路径的文件open,那么时间片结束后两个进程都会认为自己是这个文件的拥有者.并未是独占创建打开的.在open 函数的第二个参数中有 O_EXCL 这种打开方式,可以解决独占的问题.另外可以在多进程对一个文件写的时候,

《Linux多线程服务器端编程》读书笔记第3章

<Linux多线程服务器端编程>第3章主要讲的是多线程服务器的适用场合与常用的编程模型. 1.进程和线程 一个进程是"内存中正在运行的程序“.每个进程都有自己独立的地址空间(address space).将"进程"比喻为"人",每个人都有自己的记忆(memory),人与人通过谈话(消息传递)来交流,谈话既可以是面谈(同一台服务器),也可以在电话里谈(不同的服务器,有网络通信).面谈和电话谈的区别在于,面谈可以立即知道对方是否死了(crash,S

《Unix环境高级编程》读书笔记 第13章-守护进程

1. 引言 守护进程是生存期长的一种进程.它们常常在系统引导装入时启动,仅在系统关闭时才终止.它们没有控制终端,在后台运行. 本章说明守护进程结构.如何编写守护进程程序.守护进程如何报告出错情况. 2. 守护进程的特征 基于BSD的系统下执行:ps -axj -a 显示由其他用户所拥有的进程的状态:-x 显示没有控制终端的进程状态:-j 显示与作业有关的信息 基于System V的系统下执行:ps -efj Linux下执行以上两个命令输出一致 常见的守护进程: kswapd,内存换页守护进程.

《Unix环境高级编程》读书笔记 第8章-进程控制

1. 进程标识 进程ID标识符是唯一.可复用的.大多数Unix系统实现延迟复用算法,使得赋予新建进程的ID不同于最近终止所使用的ID ID为0的进程通常是调度进程,也常被称为交换进程.它是内核的一部分,是系统进程. ID为1的进程通常是init进程,在自举过程结束时由内核调用.该进程负责在内核自举后启动一个Unix系统,它决不会终止,是一个普通的用户进程,但以超级用户特权运行. ID为2的进程是页守护进程,负责支持虚拟存储器系统的分页操作. #include <unistd.h> pid_t

《Unix环境高级编程》读书笔记 第10章-信号

1.引言 信号是软件中断. 信号提供了一种处理异步事件的方法. 2. 信号概念 信号的名字都是以3个字符SIG开头. Linux3.2.0支持31种信号.FreeBSD.Linux和Solaris作为实时扩展都支持另外的应用程序定义的信号. 在头文件signal.h(其中include的bits/signum.h)中,信号名都被定义为正整数常量,不存在编号为0的信号.kill函数对信号编号0有特殊的应用. 很多条件可以产生信号: 用户按下某些终端键时:Ctrl+C.Ctrl+\.Ctrl+Z 硬

《Unix环境高级编程》读书笔记 第11章-线程

1. 引言 了解如何使用多个控制线程在单进程环境中执行多个任务. 不管在什么情况下,只要单个资源需要在多个用户键共享,就必须处理一致性问题. 2. 线程概念 典型的Unix进程可以看成只有一个控制线程:一个进程在某一时刻只能做一件事情. 多线程带来的好处: 通过为每种事件类型分配单独的处理线程,可以简化处理异步事件的代码.每个线程在进行事件处理时可以采用同步编程模式. 多个进程必须使用操作系统提供的复制机制才能实现内存和文件描述符的共享.而多个线程自动地可以访问相同的存储空间和文件描述符. 有些