第3章 Unix/Linux进程管理
1. Unix/Linux中的进程
什么是进程:
进程是计算机中正在执行的程序的实例。每个进程有自己的内存空间、寄存器状态、文件描述符等信息,使其独立于其他进程。
进程通常包括程序代码、数据、栈、堆以及进程控制块(Process Control Block,PCB)等信息。
进程状态:
进程可以处于不同的状态,包括运行(Running)、就绪(Ready)、阻塞(Blocked)等。
进程状态的转换是通过操作系统的调度器来管理的。
进程标识符:
每个进程都有一个唯一的标识符,称为进程ID(Process ID,PID)。PID 是整数值,用于在系统中唯一标识一个进程。
进程创建:
进程可以通过调用系统调用(例如 fork() 或 exec()) 来创建新的进程。
fork() 创建子进程,而 exec() 替换当前进程的内容为新程序。
父进程和子进程:
连接在一起的进程中,由一个父进程创建的进程称为子进程。子进程继承了父进程的资源和环境。
进程终止:
进程可以正常终止,也可以由操作系统或其他进程强制终止。
终止的进程会释放资源,但它的退出状态可以被其他进程检测。
进程间通信(IPC):
进程之间可能需要进行通信,以共享数据或进行协作。Unix/Linux 提供了多种 IPC 机制,如管道、消息队列、共享内存和套接字等。
僵尸进程:
僵尸进程是已经终止但其父进程尚未收回其资源或检测其终止状态的进程。
父进程应使用 wait() 或 waitpid() 等系统调用来处理子进程的退出状态。
守护进程:
守护进程是在后台运行的系统服务进程,通常没有控制终端。它们通常在系统启动时启动,并负责执行系统任务。
进程调度:
还有操作系统的任务是有效地调度进程以共享 CPU 时间。调度策略可以是抢占式或协作式,具体取决于操作系统的设计。
进程优先级:
进程可以具有不同的优先级,以决定它们获得 CPU 时间的顺序。
进程控制块(PCB):
PCB 包含了进程的关键信息,包括进程状态、寄存器状态、程序计数器、进程ID等。操作系统使用 PCB 来管理进程。
进程资源限制:
操作系统可以通过资源限制来管理进程的资源使用,如内存、文件描述符、CPU 时间等。
了解这些知识点有助于理解和管理 Unix/Linux 操作系统中的进程,以及执行多任务处理、系统管理和应用程序开发等任务。
2. 进程管理的系统调用
创建进程(Fork): 通过系统调用创建新的进程,通常在父进程的基础上复制。新进程在独立的地址空间中执行。
程序替换(Exec): 允许一个进程加载并执行另一个程序,覆盖自己的内存和代码。这是通过一系列Exec系统调用来实现的。
进程终止(Exit): 让进程正常退出,释放其资源和内存。这也可以传递退出状态码给父进程。
等待进程(Wait): 允许父进程等待其子进程的终止,并收集其退出状态。
进程调度(Scheduling): 操作系统通过调度算法决定哪个进程应该在CPU上执行,以及何时切换进程。
进程间通信(IPC): 提供机制来允许进程之间的通信,如管道、消息队列、共享内存等。
信号处理(Signal Handling): 进程可以通过信号向其他进程发送异步通知,用于处理异常事件或通信。
进程状态查询(Get Process Status): 可以获取关于进程状态和信息的系统调用,如进程ID、父进程ID、进程状态等。
这些系统调用使操作系统能够有效地管理和协调多个并发执行的进程,实现进程的创建、执行、通信和终止等功能
创建进程(Fork): 通过系统调用创建新的进程,通常在父进程的基础上复制。新进程在独立的地址空间中执行。
程序替换(Exec): 允许一个进程加载并执行另一个程序,覆盖自己的内存和代码。这是通过一系列Exec系统调用来实现的。
进程终止(Exit): 让进程正常退出,释放其资源和内存。这也可以传递退出状态码给父进程。
等待进程(Wait): 允许父进程等待其子进程的终止,并收集其退出状态。
进程调度(Scheduling): 操作系统通过调度算法决定哪个进程应该在CPU上执行,以及何时切换进程。
进程间通信(IPC): 提供机制来允许进程之间的通信,如管道、消息队列、共享内存等。
信号处理(Signal Handling): 进程可以通过信号向其他进程发送异步通知,用于处理异常事件或通信。
进程状态查询(Get Process Status): 可以获取关于进程状态和信息的系统调用,如进程ID、父进程ID、进程状态等。
这些系统调用使操作系统能够有效地管理和协调多个并发执行的进程,实现进程的创建、执行、通信和终止等功能
3. 管道
管道(Pipe):
管道是一种进程间通信(IPC)的机制,用于在两个进程之间传输数据。在Unix/Linux系统中,管道是一种特殊的文件,它将一个进程的输出连接到另一个进程的输入,形成一个数据流。这种数据流使得一个进程的输出可以直接作为另一个进程的输入,实现了进程间的数据共享。
特点和用途:
单向通信: 管道是单向通信的,通常用于将一个进程的输出传递给另一个进程的输入。
匿名管道(Anonymous Pipe): 最常见的管道形式,由shell操作符“|”创建。它通常用于将一个命令的输出传递给另一个命令作为输入。
进程间数据传输: 管道用于在相关的进程之间传输数据,实现数据共享和处理。
父子进程通信: 管道常用于父进程和子进程之间的通信,子进程的输出可以通过管道传递给父进程。
管道符号: 在命令行中,管道使用竖线符号“|”表示,例如:command1 | command2 表示将command1的输出传递给command2。
注意事项:
单向性: 管道是单向的,如果需要双向通信,需要建立两个管道。
有限缓冲区: 管道有一个有限的缓冲区,当缓冲区满时,写入进程可能会被阻塞,直到读取进程读取数据为止。
进程同步: 管道通常用于进程同步,确保写入进程的数据不会被读取进程同时读取,以免出现数据混乱的情况。
管道是Unix/Linux系统中非常重要且常用的进程间通信方式,它简单而有效,使得不同进程能够协同工作,完成更复杂的任务。
苏格拉底挑战