网站首页 > 文章精选 正文
Linux 操作系统中的进程是其核心概念之一,理解进程对于系统管理、程序开发和故障排查都至关重要。下面我们将详细解析 Linux 进程的相关知识点。
1. 什么是进程?
在 Linux(及其他类 Unix 系统)中,进程是程序执行的一个实例。当你在终端输入一个命令或双击一个应用程序图标时,操作系统就会创建一个或多个进程来执行相应的程序。
一个进程通常包括:
* 程序代码: 正在执行的指令。
* 数据: 进程使用的变量、堆栈等。
* 资源: 进程正在使用的文件、内存、网络连接等。
* 执行上下文: 包含了进程的当前状态,例如寄存器值、程序计数器等,以便在进程切换时能够恢复执行。
2. 进程的状态
进程在其生命周期中会经历多种状态,这些状态反映了它是否在运行、等待资源或已被终止。常见的进程状态包括:
* 运行 (Running / R): 进程正在 CPU 上执行,或者已经准备好在 CPU 上执行(等待调度器分配 CPU 时间片)。
* 可中断睡眠 (Interruptible Sleep / S): 进程正在等待某个事件发生(如 I/O 操作完成、某个信号的到来),在此期间它可以被信号唤醒。大多数在等待 I/O 的进程都处于此状态。
* 不可中断睡眠 (Uninterruptible Sleep / D): 进程正在等待一个非常重要的事件发生(通常是硬件 I/O),在此期间它不能被信号唤醒。处于 D 状态的进程很难被杀死,除非它等待的事件发生或者系统重启。
* 停止 (Stopped / T): 进程被暂停执行,通常是由于接收到 SIGSTOP、SIGTSTP、SIGTTIN 或 SIGTTOU 信号。进程可以通过 SIGCONT 信号继续执行。
* 僵尸 (Zombie / Z): 进程已经终止,但其父进程尚未读取其退出状态。僵尸进程本身不占用内存和 CPU 资源,只占用进程表中的一个条目。如果父进程没有处理,它们会一直存在直到父进程终止。
* 死亡 (Dead / X): 进程已终止且其父进程已读取其退出状态。此状态非常短暂,通常在 ps 命令中不常见。
可以使用 ps aux 或 top 命令查看进程状态。
3. 进程的属性
每个进程都有一些关键属性,用于标识和管理:
* PID (Process ID): 进程的唯一标识符。
* PPID (Parent Process ID): 创建当前进程的父进程的 ID。每个进程(除了 PID 为 1 的 init 或 systemd 进程)都有一个父进程。
* UID (User ID): 运行该进程的用户 ID。
* EUID (Effective User ID): 进程实际执行时所具有的权限的用户 ID。
* GID (Group ID): 运行该进程的组 ID。
* EGID (Effective Group ID): 进程实际执行时所具有的权限的组 ID。
* TTY: 进程控制终端的名称(如果有)。
* CPU 使用率 (%CPU): 进程占用 CPU 的百分比。
* 内存使用量 (%MEM, VSZ, RSS): 进程占用的虚拟内存、常驻内存等。
* 优先级 (PRI, NI):
* PRI (Priority): 进程的调度优先级,值越小优先级越高。
* NI (Nice Value): 用户可以调整的优先级,范围从 -20(最高优先级)到 19(最低优先级)。默认是 0。nice 命令用于启动时设置,renice 用于运行时修改。
4. 进程的生命周期
* 创建 (Creation):
* fork() 系统调用: 创建一个子进程,它是父进程的精确副本(除了 PID 和 PPID)。子进程继承父进程的大部分资源,但拥有独立的内存空间。
* exec() 系统调用: 在现有进程的上下文中加载并执行一个新的程序。exec 系列函数会替换当前进程的代码、数据和堆栈,但 PID 不变。通常,一个新进程的创建流程是 fork() 后立即 exec()。
* 执行 (Execution): 进程在 CPU 上执行指令,根据其代码逻辑进行操作。
* 终止 (Termination): 进程完成任务或发生错误时会终止。
* 正常终止: 进程执行完毕,或者调用 exit() 系统调用。
* 异常终止: 进程收到终止信号(如 SIGTERM、SIGKILL)或发生未处理的错误(如段错误)。
* 僵尸进程: 当子进程终止后,如果父进程没有及时调用 wait() 或 waitpid() 系统调用来回收其资源和获取其退出状态,子进程就会成为僵尸进程。
5. 进程的类型
* 前台进程 (Foreground Process): 与终端交互的进程,可以直接接收用户输入,并将输出显示在终端上。当终端关闭时,前台进程通常也会终止。
* 后台进程 (Background Process): 在后台运行的进程,不与终端交互。可以使用 & 符号在命令末尾启动后台进程。
./my_script.sh &
可以使用 jobs 命令查看当前终端的后台作业。
* fg [job_id]: 将后台进程切换到前台。
* bg [job_id]: 将停止的前台进程切换到后台。
* 守护进程 (Daemon Process): 一种特殊的后台进程,它在后台运行,不与任何终端关联。通常在系统启动时启动,并在系统关闭时终止。它们执行系统级任务,如 web 服务器 (httpd)、数据库服务器 (mysqld) 等。守护进程的父进程通常是 init (PID 1)。
6. 进程间通信 (IPC - Inter-Process Communication)
进程之间需要共享数据或进行协作时,就需要 IPC 机制。常见的 IPC 方式包括:
* 管道 (Pipes):
* 匿名管道 (|): 只能在具有亲缘关系的进程(父子进程)之间使用,通常用于命令行中的命令连接。
* 命名管道 (FIFOs): 可以在不相关进程之间使用,通过文件系统中的特殊文件进行通信。
* 信号 (Signals): 软件中断,用于通知进程发生了特定事件(如终止、挂起、继续等)。
* 消息队列 (Message Queues): 进程可以将消息放入队列,其他进程可以从队列中读取消息。
* 共享内存 (Shared Memory): 多个进程映射同一块物理内存区域,从而实现高速数据共享。需要同步机制(如信号量)来避免数据冲突。
* 信号量 (Semaphores): 用于同步进程对共享资源的访问,防止竞态条件。
* 套接字 (Sockets): 最通用的 IPC 机制,可以在同一台机器上的进程间通信,也可以在网络上的不同机器间通信。
7. 进程管理命令
* ps: 显示当前正在运行的进程。
* ps aux: 显示所有用户的所有进程,包含详细信息。
* ps -ef: 以完整格式显示所有进程。
* ps -eLf: 显示所有线程。
* top: 实时显示进程信息,按 CPU 或内存使用率排序。
* 在 top 界面中,可以按 M (内存), P (CPU) 进行排序。
* 按 k 杀死进程。
* htop: 交互式进程查看器,比 top 更用户友好。
* pgrep: 根据名称或其他属性查找进程 ID。
* pgrep firefox: 查找 firefox 进程的 PID。
* pkill: 根据名称或其他属性发送信号给进程。
* pkill firefox: 杀死所有 firefox 进程。
* kill: 向指定 PID 的进程发送信号。
* kill <PID>: 默认发送 SIGTERM (终止信号)。
* kill -9 <PID>: 发送 SIGKILL (强制终止信号,不可被捕获或忽略)。
* killall: 根据进程名称发送信号给所有匹配的进程。
* killall nginx: 杀死所有 nginx 进程。
* nice: 以指定的优先级启动命令。
* nice -n 10 my_command: 以较低优先级启动 my_command。
* renice: 改变已运行进程的优先级。
* renice -n 5 <PID>: 提高进程优先级。
* nohup: 即使终端关闭,也让命令在后台继续运行。
* nohup my_command &: 运行 my_command,并将其输出重定向到 nohup.out。
* jobs: 列出当前 shell 中的后台作业。
* fg: 将后台作业切换到前台。
* bg: 将停止的前台作业切换到后台。
* pstree: 以树状结构显示进程关系。
* /proc 文件系统: 这是一个虚拟文件系统,提供了对内核数据结构的接口。每个进程在 /proc 目录下都有一个以其 PID 命名的子目录,其中包含该进程的详细信息(如 /proc/<PID>/status、/proc/<PID>/cmdline、/proc/<PID>/fd 等)。
8. 线程 (Threads)
* 进程 vs. 线程:
* 进程是操作系统资源分配的最小单位,拥有独立的地址空间、文件描述符等资源。
* 线程是 CPU 调度的最小单位,是进程内的一个执行流。同一个进程中的所有线程共享该进程的地址空间和大部分资源,但每个线程有独立的程序计数器、栈和寄存器。
* 优点: 线程比进程更轻量级,创建和销毁的开销更小,线程间通信更高效。
* 管理: 在 Linux 中,线程通常被称为“轻量级进程”(LWP - Light-Weight Process)。ps -eLf 命令可以查看线程信息。
9. 进程调度
Linux 内核的调度器负责在多个进程之间分配 CPU 时间。其目标是:
* 公平性: 确保所有进程都能获得 CPU 时间。
* 响应性: 确保交互式进程能够及时响应用户输入。
* 吞吐量: 最大化 CPU 利用率,完成更多工作。
调度器会根据进程的优先级、历史行为(如是否是 I/O 密集型或 CPU 密集型)来决定哪个进程在何时运行。
10. 系统启动中的进程
* init (System V init) 或 systemd (现代 Linux): PID 为 1 的进程是所有其他用户空间进程的祖先。它负责初始化系统、启动服务(守护进程),并回收孤儿进程(父进程先于子进程终止的子进程会被 init/systemd 收养)。
理解这些进程相关的知识点,能够帮助你更好地诊断系统问题、优化程序性能,并编写更健壮的 Shell 脚本。
- 上一篇: Linux系统编程之进程基础知识
- 下一篇: Linux 进阶知识点总结
猜你喜欢
- 2025-05-26 Linux新手必备:20个高效命令轻松掌握!
- 2025-05-26 Linux 常用命令集合
- 2025-05-26 [面试题]面试官: 在linux系统中,如何知道一个进程的启动时间?
- 2025-05-26 Linux 进阶知识点总结
- 2025-05-26 Linux系统编程之进程基础知识
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)