全方位剖析 Linux 操作系统,太全了( 七 )


套接字有以下几种分类

  • 顺序包套接字(Sequential Packet Socket): 此类套接字为最大长度固定的数据报提供可靠的连接 。此连接是双向的并且是顺序的 。
  • 数据报套接字(Datagram Socket):数据包套接字支持双向数据流 。数据包套接字接受消息的顺序与发送者可能不同 。
  • 流式套接字(Stream Socket):流套接字的工作方式类似于电话对话,提供双向可靠的数据流 。
  • 原始套接字(Raw Socket): 可以使用原始套接字访问基础通信协议 。
Linux 中进程管理系统调用现在关注一下 Linux 系统中与进程管理相关的系统调用 。在了解之前你需要先知道一下什么是系统调用 。
操作系统为我们屏蔽了硬件和软件的差异,它的最主要功能就是为用户提供一种抽象,隐藏内部实现,让用户只关心在 GUI 图形界面下如何使用即可 。操作系统可以分为两种模式
  • 内核态:操作系统内核使用的模式
  • 用户态:用户应用程序所使用的模式
我们常说的上下文切换 指的就是内核态模式和用户态模式的频繁切换 。而系统调用指的就是引起内核态和用户态切换的一种方式,系统调用通常在后台静默运行,表示计算机程序向其操作系统内核请求服务 。
系统调用指令有很多,下面是一些与进程管理相关的最主要的系统调用
forkfork 调用用于创建一个与父进程相同的子进程,创建完进程后的子进程拥有和父进程一样的程序计数器、相同的 CPU 寄存器、相同的打开文件 。
execexec 系统调用用于执行驻留在活动进程中的文件,调用 exec 后,新的可执行文件会替换先前的可执行文件并获得执行 。也就是说,调用 exec 后,会将旧文件或程序替换为新文件或执行,然后执行文件或程序 。新的执行程序被加载到相同的执行空间中,因此进程的 PID不会修改,因为我们没有创建新进程,只是替换旧进程 。但是进程的数据、代码、堆栈都已经被修改 。如果当前要被替换的进程包含多个线程,那么所有的线程将被终止,新的进程映像被加载执行 。
这里需要解释一下进程映像(Process image) 的概念
什么是进程映像呢?进程映像是执行程序时所需要的可执行文件,通常会包括下面这些东西
  • 代码段(codesegment/textsegment)
又称文本段,用来存放指令,运行代码的一块内存空间
此空间大小在代码运行前就已经确定
内存空间一般属于只读,某些架构的代码也允许可写
在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等 。
  • 数据段(datasegment)
可读可写
存储初始化的全局变量和初始化的 static 变量
数据段中数据的生存期是随程序持续性(随进程持续性)
随进程持续性:进程创建就存在,进程死亡就消失
  • bss 段(bsssegment):
可读可写
存储未初始化的全局变量和未初始化的 static 变量
bss 段中的数据一般默认为 0
  • Data 段
是可读写的,因为变量的值可以在运行时更改 。此段的大小也固定 。
  • 栈(stack):
可读可写
存储的是函数或代码中的局部变量(非 static 变量)
栈的生存期随代码块持续性,代码块运行就给你分配空间,代码块结束,就自动回收空间
  • 堆(heap):
可读可写
存储的是程序运行期间动态分配的 malloc/realloc 的空间
堆的生存期随进程持续性,从 malloc/realloc 到 free 一直存在
下面是这些区域的构成图
全方位剖析 Linux 操作系统,太全了

文章插图
 
exec 系统调用是一些函数的集合,这些函数是
  • execl
  • execle
  • execlp
  • execv
  • execve
  • execvp
下面来看一下 exec 的工作原理
  1. 当前进程映像被替换为新的进程映像
  2. 新的进程映像是你做为 exec 传递的灿睡
  3. 结束当前正在运行的进程
  4. 新的进程映像有 PID,相同的环境和一些文件描述符(因为未替换进程,只是替换了进程映像)
  5. CPU 状态和虚拟内存受到影响,当前进程映像的虚拟内存映射被新进程映像的虚拟内存代替 。
waitpid等待子进程结束或终止
exit在许多计算机操作系统上,计算机进程的终止是通过执行 exit 系统调用命令执行的 。0 表示进程能够正常结束,其他值表示进程以非正常的行为结束 。
其他一些常见的系统调用如下


推荐阅读