2.进程状态转换

发布于:2023-10-01 ⋅ 阅读:(101) ⋅ 点赞:(0)

一、进程状态

在操作系统中,进程可以处于多种状态,这些状态表示了进程在其生命周期中的不同情况。通常,进程的状态可以划分为以下几种:

  1. 创建状态(New):

    • 进程被创建但尚未被调度执行。在这个状态下,操作系统正在为进程分配资源和初始化必要的数据结构。
  2. 就绪状态(Ready):

    • 进程已经准备好执行,但由于系统可能有多个就绪的进程,操作系统需要在它们之间进行选择,决定哪一个将获得 CPU 时间片并开始执行。
  3. 运行状态(Running):

    • 进程占用了 CPU 并正在执行。在单核处理器上,任何时刻只有一个进程处于运行状态,而在多核处理器上,多个进程可以同时处于运行状态。
  4. 阻塞状态(Blocked):

    • 进程因为某些原因而不能执行,例如等待某个事件的发生,如 I/O 操作完成或信号的到达。在阻塞状态下,进程不占用 CPU 时间。
  5. 终止状态(Terminated):

    • 进程执行完毕或被操作系统终止。在这个状态下,进程占用的资源会被释放,但它的状态信息可能会保留一段时间以供父进程查询。

这些状态通常用状态转换图表示。状态转换图说明了进程在不同状态之间的切换条件。以下是状态转换的一些基本规则:

  • 进程从就绪状态转换到运行状态,通常是因为它被调度获得了 CPU 时间片。
  • 进程在运行状态可能会因为等待某个事件而转换到阻塞状态。
  • 进程在阻塞状态可能会因为等待的事件发生而转换到就绪状态。
  • 进程在运行状态可能会因为执行完毕或出现错误而转换到终止状态。

这些状态的管理和切换由操作系统的调度器(Scheduler)负责。调度器决定了在给定时刻哪个进程应该处于运行状态,从而协调多个进程在系统中的执行。

 二、进程相关命令

一、 查看进程

ps -aux 是一个用于查看系统中当前运行进程信息的命令。在 Unix/Linux 系统中,ps 命令用于显示进程的状态信息。下面是对这个命令的解释:

  • ps 命令: 用于显示系统中当前运行的进程的状态信息。

  • -aux 选项: 这是常见的选项组合,具体含义可能因不同的操作系统而异。

  • 在 Linux 等系统中:

      • -a:显示所有终端上的进程。
      • -u:以用户为基础显示更详细的信息。
      • -x:显示没有控制终端的进程。
    • 总体而言,-aux 选项组合通常用于显示系统上所有用户的所有进程,并提供详细的信息,包括进程的状态、CPU 使用率、内存占用等。输出包含很多列,其中包括用户、PID(进程ID)、%CPU(CPU使用率)、%MEM(内存使用率)、VSZ(虚拟内存大小)、RSS(物理内存大小)、TTY(终端类型)、STAT(进程状态)等等。

二 、杀死进程 
  • -l 列出可用的信号列表。
  • -9 发送强制终止信号(SIGKILL),会立即终止进程,不能被捕获或忽略。
  • -15(默认): 发送终止信号(SIGTERM),请求进程正常终止。

在 Unix/Linux 操作系统中,信号是一种用于进程间通信的机制。通过信号,一个进程可以向另一个进程或自身发送通知,告知发生了某个事件。信号可用于各种目的,包括通知进程终止、重新启动、刷新配置等。

每个信号都有一个唯一的标识符,通常用整数表示。这些标识符定义在 <signal.h> 头文件中。以下是一些常见的信号及其标识符:

  1. SIGHUP (1): 连接断开。
  2. SIGINT (2): 中断进程(通常由 Ctrl+C 产生)。
  3. SIGQUIT (3): 退出进程(通常由 Ctrl+\ 产生)。
  4. SIGILL (4): 非法指令。
  5. SIGTRAP (5): 跟踪/断点陷阱。
  6. SIGABRT (6):abort() 生成的终止进程。
  7. SIGBUS (7): 总线错误。
  8. SIGFPE (8): 浮点异常。
  9. SIGKILL (9): 强制终止进程。
  10. SIGUSR1 (10): 用户自定义信号1。
  11. SIGSEGV (11): 段错误。
  12. SIGUSR2 (12): 用户自定义信号2。
  13. SIGPIPE (13): 向无读进程的管道写入数据。
  14. SIGALRM (14): 定时器超时。
  15. SIGTERM (15): 请求进程终止(默认由 kill 命令发送)。

三、 进程号和相关函数

在操作系统中,每个运行的进程都有一个唯一的标识符,称为进程号(Process ID,PID)。进程号是一个非负整数,用于区分系统中不同的进程。在 Unix/Linux 等类 Unix 操作系统中,进程号通常是分配给进程的唯一标识符,其值可以从 1 开始递增。

有一些相关的函数用于获取、管理和操作进程号,这些函数通常在 C 语言中使用。以下是一些常见的与进程号相关的函数:

  1. getpid()

    • 函数原型:pid_t getpid(void);
    • 用于获取调用进程的进程号(PID)。
  2. getppid()

    • 函数原型:pid_t getppid(void);
    • 用于获取调用进程的父进程的进程号(Parent Process ID)。
  3. fork()

    • 函数原型:pid_t fork(void);
    • 创建一个新的进程,新进程是调用进程的副本。在父进程中,fork() 返回子进程的 PID;在子进程中,它返回 0。
  4. waitpid()

    • 函数原型:pid_t waitpid(pid_t pid, int *status, int options);
    • 等待指定的子进程结束,获取其退出状态。如果指定了 pid 为 -1,则等待任意子进程结束。
  5. exec 系列函数:

    • execl, execle, execlp, execv, execve, execvp 等。
    • 这些函数用于加载新的程序替代当前进程的镜像。执行成功后,调用进程的 PID 不变,但代码、数据和堆栈等内容会被新程序替代。
  6. exit()

    • 函数原型:void exit(int status);
    • 终止调用进程,并返回一个状态码给其父进程。

这些函数提供了一系列的工具,用于获取和管理进程号,以及在进程间进行通信和控制。在实际编程中,这些函数通常与其他系统调用和库函数一起使用,以实现对进程的有效管理。