侧边栏壁纸
博主头像
Johnny博主等级

学无先后,达者为师

  • 累计撰写 9 篇文章
  • 累计创建 4 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

Linux-Unix系统编程手册学习笔记

Johnny
2022-11-20 / 0 评论 / 0 点赞 / 12 阅读 / 4,056 字

2.基本概念

这一节基本上就只有概念性的问题。所以可能比较简略。

操作系统的核心——内核

操作系统包含两种含义:

第一种是完整的软件包;第二是管理和分配计算机资源的核心层软件。

第一种中说到的完整的软件包包括第二种的软件和附带的软件工具,比如说图形化界面,文件操作工具等。

内核的职责

进程调度:首先计算机拥有着一个或者多个CPU。进程储存于内存当中,内存中停留的进程都能获得CPU的使用权。同时Linux属于抢占式多任务操作系统,这里面的抢占是一组规则,对于进程使用CPU的方式进行了规定,进程调度就实施这些规定来管理进程使用CPU。

内存管理:也就是由于物理内存有限,所以操作系统必须对于物理内存进行管理。这是显然的。然后书中在这一段中也提到了Linux使用虚拟内存管理机制,会在后面的章节提到。这里就照抄原话了:

image-20221120151508492

提供文件系统:方便用户对磁盘中的文件进行创建、获取、更新、删除等操作

创建和终止进程:内核可将新程序载入内存,然后进行进程调度来使用程序。当程序关闭时,要去释放它之前所获得的资源,方面别的进程使用。

对设备的访问:内核要为程序提供访问外部设备的接口,同时要仲裁多个进程对同一个设备的访问

联网:以用户进程的名义收发数据包,包括将网络数据包路由到目标系统

提供系统调用API:进程可使用内核入口点请求内核完成任务

书中还提到了Linux的虚拟私有计算机(virtual private computer),内核负责解决多进程情况下引发的冲突。

内核态和用户态

首先这两个状态的切换是由硬件指令去切换的。

其次虚拟内存会被划分为:用户空间部分内核空间部分,显然在内核态的时候可以访问这两个状态,用户态的时候只能访问用户空间部分。

书上给了一个例子:内核空间态用啥用?这样可以在内核态的时候执行一些操作,比如说宕机、访问内存管理硬件、初始化IO等等。这确保了用户不会访问到内核指令和数据结构。

Shell

shell是一种程序,用来读取用户输入的命令,并执行相应的程序以响应命令。

用户和组

系统会对每个用户的身份做唯一标识,用户可隶属于多个组。

用户

系统的每一个用户都有一个ID 成为UID。系统有一个密码文件为每个用户都定义一行记录。包含有用户名 、UID、组ID、主目录、登录shell

为了控制对文件和其他资源的访问,给多个用户进行了分组。与用户相似,/etc/group中记录着组的信息,组名、组ID、用户列表

超级用户

就是常见的root,他的UID都是0,超级用户能执行一切操作来管理操作系统。

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

文件类型

普通文件或纯文本文件:表示普通数据文件

其他文件类型:设备、管道、套接字、目录、符号链接

路径和链接

目录是一种特殊类型的文件,数据项有文件名对应文件的引用,“文件名+引用”叫做链接。

每个文件都可以用多条链接,也可以有多个名称。

emmm这里读的时候有些不太懂链接是啥。其实这里具体指的是硬链接。可以简单理解为Windows中的快捷方式,让一些深层次的文件更容易访问,相当于创建了一个指针指向了该文件的储存地址

符号链接

也称作软链接,就是给文件起了一个别名。创建了一个文件指向引用文件的路径,当引用文件发生移动时,再访问软链接就访问不到了。

文件IO模型

对于UNIX同一套系统调用所执行的IO操作可施与所有文件类型,包括设备文件。

image-20221120162246781

程序

过滤器

从stdin读取输入,加以转换,再将转换后的数据输出到stdout,常常将拥有上述行为的程序成为过滤器。 cat grep awk都是过滤器

命令行参数

这很容易理解了,就不写了

进程

进程是正在执行的程序实例。执行程序的时候,内核将程序代码载入虚拟内存,为程序变量分配空间,建立内核记账(bookkeeping)数据结构,记录了进程的信息。

进程的内存布局

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

创建进程和执行程序

​ 进程可使用系统调用fork()来创建一个新进程。调用fork的的进程叫做父进程,新创建的进程当然就是子进程。子进程从父进程那继承复制了一份数据、堆、栈,可以修改,并且并不影响父进程的段的内容,也就是子进程的段是独立的。再内存中被标记为只读的程序文本段由父子进程共享。

​ 子进程,要么执行父进程共享出来的代码的另一个函数,要么就是调用execve()去加载并执行另一个全新的程序。值得注意的是execve()会销毁文本段、数据段、堆段、栈段,根据加载的代码重新创建一个。

进程ID和父进程ID

​ 每一个进程都有一个唯一的整数型进程标识符PID,每一个进程还有一个父进程标识符PPID,用于向内核请求创建自己的进程。

进程终止和终止状态

​ 有两种方式来终止一个进程:

  • 使用_exit()系统调用,请求退出
  • 向进程传递信息,将其杀死

退出时会有一个终止状态,一个非负的小整数,可供父进程的wait()系统调用检测。

进程的用户和组标识符

每个进程都有一个与之相关的用户ID和组ID

  • 真实用户ID和组ID:用来表示进程所属的用户和组。新进程从父进程继承这些ID,login shell则从系统密码文件中读取相应的字段来获得这些ID
  • 有效用户ID和组ID:进程再访问受保护资源时,会使用这两个ID来确定访问权限。一般情况下和真实用户ID和组ID相同
  • 补充组ID:用来标识进程所属的额外组。获取补充组ID与获取真实用户ID相同

特权进程

通常指的是root用户创建的ID,内核所施加的权限限制对此类进程无效。

由某一特权进程创建的进程也可以是特权进程。成为特权进程的另一种方法是 set-user-ID 机制,该机制允许某进程的有效用户ID等同于该进程所执行程序文件的用户ID

能力

​ Linux把传统上赋予超级用户的权限划分为一组相互独立的单元(称之为能力)。每次特权操作都与特定的能力相关,仅当进程具有特定的能力时,才能执行相应的操作。

init进程

​ init进程是所有进程的父进程,所有进程都是init进程fork()出来的或者是它的子进程fork的。所有的用户都不能kill掉这个进程,只有关闭系统时才能终止这个进程。

守护进程

  • 他的生命周期与init线程一样
  • 同时这个进程在后台运行,无控制终端供其读取或写入数据

书上给了两个例子:syslog(在系统日志中记录消息)和httpd

环境列表

​ 也就是我们平常添加的环境变量所在的表。子进程是继承父进程的环境列表,或者是在调用exec()系统调用时添加新环境。

资源限制

​ 每个进程都会消耗系统资源。所以使用系统调用setrlimit(),进程可为自己消耗的各类资源设定一个上限。非特权进程在针对特定资源调整软限制值时,可将其设置为0到硬限制之间的值,硬限制只能调低不能调高

​ 由fork创建的进程会继承父进程的资源限制

​ 使用ulimit命令可调整shell的资源限制。

内存映射

​ 调用系统函数mmap()的进程,会在虚拟地址空间中创建一个新的内存映射

  • 文件映射:将文件的部分区域映射入调用进程的虚拟内存。文件被映射后,可以通过访问虚拟内存来访问文件内容;
  • 匿名映射:没有映射对应的相关文件,这种映射的内存区域的内容会被初始化为0。

反正读到这我是懵逼的。。。。。。,之后会有章节详细介绍。

由某一进程所映射的内存可与其他进程共享。共享的方式有两个:一个是两个进程都对同一个文件的相同部分都映射上了,第二个当然就是子进程继承父进程的映射。共享也分为私有和共享。

对于私有,一个进程对于映射内容的修改对其他共享进程不可见。

静态库和共享库

目标库:将一组函数代码加以编译,置于一个文件中,供其他应用程序调用。

静态库

​ 静态库是对已编译的目标模块的一种结构化整合,在链接器解析了引用情况后,会从库中抽取所需目标模块的副本,将其复制到最终的可执行文件中。

共享库

​ 将程序链接到共享库中,链接器就不会把库中的目标模块复制到可执行文件中,而是在可执行文件中写入一条数据,表明运行时需要从共享库中得到目标模块。

进程间通信及同步

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

  • 信号,用来表示事件的发生
  • 管道和FIFO,用于在进程中传递数据
  • 套接字,供同一台主机或是联网的不同主机上所运行的进程之间传递数据
  • 文件锁定,方式其他进程读取或者更新文件内容
  • 消息队列,用于在进程间交换消息
  • 信号量,用来同步进程动作
  • 共享内存,允许两个及以上进程共享一块内存,当某进程改变了共享内存的内容,其他进程也会了解到这个变化

信号

信号代表着某一事件或异常情况的发生。

内核、其他进程、进程自身均可向进程发送信号。

信号从产生直至送达进程期间一直处于挂起状态,通常系统会在接收进程下次获得调度时,将处于挂起状态的信号同时送达。如果接收进程正在运行,则信号会立刻送达。然后如果信号被纳入信号屏蔽以求阻塞该信号。如果信号处于信号屏蔽之内,那么信号会一直处于挂起状态。

线程

每个进程可以属于多个线程中。可以把线程想象为共享同一虚拟内存,都执行相同的代码,共享数据区域和堆,但是线程都拥有属于自己的栈。

​ 线程之间可以通过共享的全局变量进行通信。

进程组和shell任务控制

shell执行的每个程序都会在一个新进程内发起。

shell会将管道内的所有进程置于一个新进程组或任务中

如书上的例子

$ ls -l | sort -k5n | less

这是三个进程,属于一个进程组

会话、控制终端和控制进程

​ 会话指的是一组进程组任务。会话中的所有进程都具有相同的会话标识符。会话首进程是指创建会话的进程,

其进程ID会成为会话ID

​ 通常会话都会与某个控制终端相关。控制终端建立于会话首进程初次打开终端设备之时。

伪终端

​ 伪终端是一对相互连接的虚拟设备,也称为主从设备。在这对设备之间设有一条IPC信道,可提供数据进行双向传递。

读到这我是一脸懵逼。。。。。

伪终端(pty)是指伪终端master和伪终端slave这一对字符设备,Linux 的伪终端驱动程序,会把 master 端(如键盘)写入的数据转发给 slave 端供程序输入,把程序写入 slave 端的数据转发给 master 端供(显示器驱动等)读取。

日期和时间

有两种时间 真实时间和进程时间

客户端/服务器架构

客户端/服务器应用有:客户端和服务端组成

两个相互通讯需要IPC机制

实时性

实时性的应用是指那些需要对输入做出及时响应的应用程序。

为支持实时性,POSIX.1b定义了拓展,包括 异步I/O、共享内存、内存映射文件、内存锁定、实时性时钟和定时器、备选调度策略、实时性信号、消息队列以及信号量等

/proc文件系统

他是一种虚拟文件系统,以文件系统目录和文件形式,提供一个指向内核数据结构的接口,还提供了一组以/proc/PID形式命名的目录查看系统中运行的各进程的相关信息。

总结

这一章基本就是对后面的章节的一个概括,我觉得不要过于全部理解,到后面的章节有详细的例子,到时候再深究。

0

评论区