Linux中如何查看进程信息
tophtop(首选htop),atopglancesps(极其灵活),pstree(看关系)pgreppidofpkillkillallkillvmstatuptimesar(历史)/proc文件系统 (最底层),pmap(内存映射),lsof(打开文件/网络)straceltracetimenumastat(NUMA),taskset(CPU亲和性),slabtop(内核缓存)procrank
Linux中如何查看进程信息
这节我们来详细介绍一下 Linux 中查看进程信息的指令,按照从最常用到不太常用的顺序进行罗列和说明:(本文中指令的使用展示是在CentOS 7.9版本下进行)
指令查看
一、最常用 (日常监控和管理必备)
-
top- 用途: 动态、实时地显示系统中运行的进程信息及其资源占用情况(CPU、内存等)。它是交互式的,可以排序、杀死进程等。
- 特点: 信息全面、实时更新、交互操作。是系统性能监控的首选工具。
- 常用快捷键:
P(大写):按 CPU 使用率排序M(大写):按内存使用率排序T(大写):按运行时间排序k:杀死进程 (输入进程 PID)r:调整进程优先级 (renice)h:显示帮助q:退出 top
- 示例:
top 
-
htop(需要安装,通常不是默认自带,但极其推荐)- 用途:
top的增强版,提供更直观、更易用的界面(彩色显示、水平/垂直滚动、鼠标支持、树状视图等)。 - 特点: 可视化更好,操作更方便(鼠标点击选择、杀死进程等),功能更丰富(如进程树查看)。
- 常用快捷键: 与
top类似,但界面更友好。F5切换树状视图,F6选择排序方式,F9杀死进程等。 - 示例:
htop(如果未安装,通常sudo apt install htop或sudo yum install htop) 
- 用途:
-
ps- 用途: 提供当前进程状态的静态快照。功能极其强大,参数组合繁多。
- 特点: 输出格式灵活可控,适合在脚本中使用或获取特定进程的精确信息。
- 最常用组合:
ps aux:BSD 风格,显示所有用户的所有进程详细信息(USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMAND)。ps -ef:标准 UNIX (SysV) 风格,显示所有进程信息(UID, PID, PPID, C, STIME, TTY, TIME, CMD)。ps -eF/ps -ely:提供更详细的格式(包括优先级、nice值、驻留内存等)。ps -eo pid,ppid,cmd,%cpu,%mem --sort=-%cpu:自定义输出列并按 CPU 降序排序。
- 示例:
-
查看所有进程:
ps aux -

-
查看特定用户的进程:
ps -u username -

-
查看特定进程(如 bash):
ps aux | grep bash -

-
-
pstree- 用途: 以树状结构显示进程及其父子关系。
- 特点: 直观展示进程间的层次结构,有助于理解进程是如何启动的。
- 常用选项:
-p:显示进程 PID-u:显示进程所属用户-a:显示命令行参数
- 示例:
pstree -p(显示带 PID 的进程树) 
二、常用 (特定场景下非常有用)
-
pgrep- 用途: 根据进程名称或其他属性查找进程的 PID。
- 特点: 简洁高效,特别适合在脚本中使用。
- 常用选项:
-l:同时列出进程名和 PID-u username:查找特定用户的进程-f:匹配完整的命令行(而不仅仅是进程名)
- 示例:
-
查找名为 “ssh” 的进程 PID:
pgrep ssh -

-
查找用户 “lx” 的 “bash” 进程,同时列出进程名和PID:
pgrep -lu lx bash -

-
-
pidof- 用途: 查找指定名称的正在运行的进程的 PID。
- 特点: 比
pgrep更简单直接,只输出 PID,适合脚本。 - 示例:
pidof bash(输出 bash主进程的 PID) 
-
pkill- 用途: 根据进程名称或其他属性向进程发送信号(默认发送
TERM信号)。 - 补充:在类 Unix 操作系统(如 Linux、macOS)中,TERM 信号(全称
SIGTERM,信号编号为 15)是一种用于请求进程优雅终止的信号,是操作系统与进程间通信的核心机制之一,用于协调进程的正常退出流程(区别于强制杀死进程)。 - 特点: 通过名称批量终止进程,非常方便。
- 常用选项:
-signal:指定发送的信号 (如-9或-KILL发送 SIGKILL)-u username:终止特定用户的进程-f:匹配完整的命令行
- 示例:
-
终止所有名为 “tt” 的进程:
pkill tt(tt是我写的一个可执行程序) -

-
强制终止用户 “jane” 的所有进程:
pkill -9 -u jane//这里我就不给大家演示了
-
- 用途: 根据进程名称或其他属性向进程发送信号(默认发送
-
kill/killall-
kill:- 用途: 通过 PID 向进程发送信号。
- 示例:
kill -9 18378(强制杀死 PID 为 18378 的进程) 
-
killall:- 用途: 通过进程名称向所有匹配的进程发送信号。
- 示例:
killall -HUP nginx(向所有 nginx 进程发送 SIGHUP 信号,使其重载配置)
-
特点:
kill是最基础的进程信号发送工具。killall按名称操作更便捷,但需注意名称匹配的准确性。
-
三、较常用 (深入分析或特定需求)
-
vmstat- 用途: 报告关于进程、内存、分页、块 IO、陷阱(中断)和 CPU 活动的信息。
- 特点: 提供系统整体资源使用的概览,包括运行/阻塞进程数量。常与
-w(宽输出) 和间隔 次数参数一起用于监控。 - 示例:
vmstat -w 1(每 1 秒刷新一次宽格式输出) 
-
lsof(List Open Files)- 用途: 列出当前系统打开的文件。由于在 Linux 中“一切皆文件”(包括网络连接、管道等),它可以用来查看哪些进程在使用特定的文件、目录、网络端口等。//目前我还没学到这个部分。
- 特点: 功能强大,用于诊断资源占用(如“无法卸载设备,资源忙”)、网络连接查看等。
- 常用选项:
-i:列出网络连接 (如lsof -i :80查看谁在使用 80 端口)-u username:列出指定用户打开的文件-c processname:列出指定进程打开的文件+D /path/to/dir:递归列出目录下被打开的文件-p PID:列出指定 PID 打开的文件
- 示例:
lsof -i TCP:22(查看所有使用 TCP 22 端口 (SSH) 的进程)
-
pmap- 用途: 报告进程的内存映射。显示进程的地址空间布局,包括动态库、堆栈、共享内存段等。//目前我还没学到这个部分。
- 特点: 用于分析进程的内存使用细节,尤其是查找内存泄漏或查看共享内存。
- 常用选项:
-x:显示更详细的信息(扩展格式)。 - 示例:
pmap -x 1234(显示 PID 1234 的详细内存映射)
-
/proc文件系统- 用途: 这不是一个命令,而是一个虚拟文件系统,内核通过它向用户空间暴露进程和系统信息。直接读取
/proc下的文件(主要是数字目录,代表 PID)可以获取极其详尽的进程信息。//这个挺好用的。 - 特点: 信息最原始、最全面。是很多进程工具(如
ps,top)的数据来源。 - 常用文件示例:
/proc/PID/status:进程状态摘要(名称、状态、PID、PPID、UID、GID、内存使用、信号等)。/proc/PID/stat//proc/PID/statm:更底层的进程状态和内存信息(供工具解析)。/proc/PID/cmdline:启动该进程的完整命令行。/proc/PID/fd/:该进程打开的所有文件描述符(链接到实际文件)。/proc/PID/maps:类似pmap的内存映射信息。/proc/PID/io:进程的 IO 统计信息(读写字节数等)。/proc/PID/cwd:进程当前工作目录的符号链接。/proc/PID/exe:进程正在执行的可执行文件的符号链接。/proc/PID/environ:进程的环境变量。
- 示例:
cat /proc/21890/status(查看 PID 21890 的状态信息) 
- 用途: 这不是一个命令,而是一个虚拟文件系统,内核通过它向用户空间暴露进程和系统信息。直接读取
四、不太常用 (特定场景或深入系统管理/调优)
这些我就不给大家演示了。
uptime- 用途: 显示系统运行时间、当前登录用户数以及过去 1、5、15 分钟的平均负载。平均负载一定程度上反映了等待运行的进程数(包括运行中和不可中断睡眠的进程)。
- 特点: 快速查看系统负载概况。
- 示例:
uptime
atop(需要安装)- 用途: 比
top和htop更强大的高级性能监控工具。记录历史性能数据,提供更详细的资源使用统计(包括磁盘、网络、每个进程的详细资源消耗历史)。 - 特点: 适合进行长期的性能分析和故障排查。
- 示例:
atop
- 用途: 比
glances(需要安装)- 用途: 基于 Python 的跨平台系统监控工具,在一个屏幕上通过 curses 或 Web 界面展示大量信息(CPU、内存、磁盘、网络、进程、文件系统、传感器等)。
- 特点: 界面美观,信息集中,扩展性强(支持插件)。
- 示例:
glances
sar(System Activity Reporter) (通常属于sysstat包)- 用途: 收集、报告和保存系统活动信息(CPU、内存、磁盘、网络、进程等)。主要用于查看历史性能数据。
- 特点: 强大的历史数据分析工具,需要配置和启用收集服务 (
sysstat)。 - 示例:
sar -u 1 3(每 1 秒采样一次 CPU 使用率,共采样 3 次)sar -r(查看内存使用历史)
slabtop- 用途: 实时显示内核 slab 缓存的使用情况。Slab 是内核用于管理数据结构缓存(如 inode, dentry)的机制。
- 特点: 用于诊断内核级的内存消耗问题。
- 示例:
slabtop(类似top的交互式界面)
time- 用途: 运行一个命令,并在命令结束后报告其使用的实际时间、用户态 CPU 时间、内核态 CPU 时间。
- 特点: 用于测量命令的执行时间和资源消耗。注意区分 shell 内置的
time和/usr/bin/time(后者通常功能更强,如-v选项)。 - 示例:
/usr/bin/time -v ls /(详细输出ls /命令的资源使用情况)
strace/ltracestrace: 跟踪进程执行的系统调用和接收到的信号。ltrace: 跟踪进程调用的库函数。- 特点: 强大的调试工具,用于分析程序行为、定位问题(如程序卡死、崩溃原因)。输出量大,需要一定专业知识解读。
- 示例:
strace -p 1234(跟踪正在运行的 PID 1234)strace ls(跟踪执行ls命令)
procrank(常见于 Android 系统或嵌入式环境,Linux 发行版可能需要特定工具)- 用途: 显示进程的内存消耗排名(USS, PSS, RSS, VSS)。
- 特点: 对分析 Android 应用内存占用特别有用。标准 Linux 上可用
smem替代。 - 示例:
procrank
numastat- 用途: 显示 NUMA (非统一内存访问) 架构下的 CPU 和内存分配统计信息。
- 特点: 用于优化在 NUMA 服务器上的应用程序性能。
- 示例:
numastat或numastat -p PID
taskset- 用途: 获取或设置进程的 CPU 亲和性(affinity),即指定进程在哪些 CPU 核心上运行。
- 特点: 用于性能调优(减少 CPU 缓存失效、绑定关键进程等)。
- 示例:
taskset -p PID(查看 PID 的亲和性)taskset -cp 0,2 PID(将 PID 绑定到 CPU 0 和 2 上运行)
指令总结
- 实时监控:
top,htop(首选htop),atop,glances - 静态快照/列表:
ps(极其灵活),pstree(看关系) - 查找 PID:
pgrep,pidof - 终止进程:
pkill,killall,kill - 系统负载/资源概览:
vmstat,uptime,sar(历史) - 深入进程细节:
/proc文件系统 (最底层),pmap(内存映射),lsof(打开文件/网络) - 调试/分析:
strace/ltrace,time - 特定硬件/优化:
numastat(NUMA),taskset(CPU亲和性),slabtop(内核缓存) - 内存分析 (特定):
procrank/smem
函数查看
在 Linux 环境下,C/C++ 提供了丰富的系统调用和库函数用于进程管理和信息获取。以下是完整的函数列表,包含头文件声明和详细的使用示例:(这部分作为初学者,我们只需要看前面两点的函数就够了,也就是进程信息函数和进程创建函数,其他的目前只作为一个扩展,等后续学到了,我们再仔细聊)
一、进程标识与基本信息函数
-
getpid- 获取当前进程 ID#include <unistd.h> pid_t getpid(void);示例:
#include <unistd.h> #include <stdio.h> int main() { printf("My PID is %d\n", getpid()); return 0; }注意:这个程序运行之后会打印它运行时候的进程的进程ID。但是当你使用指令查看该进程ID的信息的时候却找不到。这是为什么呢?这是因为进程早就结束了,就打印一个信息,一瞬间的事情。进程被调度执行完后就删除了,所以我们通过函数得知程序的进程ID后,使用指令查看,早就来不及了。
如果想程序运行起来,打印出进程ID后,你还能用指令查看相关信息,你就得给你这个程序整一个循环,最简单的就是死循环,你想退出这个程序
Ctrl+C就行了。或者 用指令pkill或者kill掉进程就ok了。下面那些函数的例子也是。可以借鉴下面这个代码。
#include <stdio.h> #include <unistd.h> int main() { pid_t pid = getpid(); pid_t ppid = getppid(); while(1) { printf("当前进程ID: %d\n",pid); printf("父进程ID: %d\n",ppid); sleep(2);//程序休眠两秒,也就是每两秒循环执行一次 } return 0; } -
getppid- 获取父进程 ID#include <unistd.h> pid_t getppid(void);示例:
#include <unistd.h> #include <stdio.h> int main() { printf("Parent PID is %d\n", getppid()); return 0; } -
getuid/geteuid- 获取用户 ID#include <unistd.h> uid_t getuid(void); // 实际用户 ID uid_t geteuid(void); // 有效用户 ID示例:
#include <unistd.h> #include <stdio.h> int main() { printf("Real UID: %d, Effective UID: %d\n", getuid(), geteuid()); return 0; } -
getgid/getegid- 获取组 ID#include <unistd.h> gid_t getgid(void); // 实际组 ID gid_t getegid(void); // 有效组 ID示例:
#include <unistd.h> #include <stdio.h> int main() { printf("Real GID: %d, Effective GID: %d\n", getgid(), getegid()); return 0; }
二、进程创建与控制函数
-
fork- 创建新进程#include <unistd.h> pid_t fork(void);示例:
#include <unistd.h> #include <stdio.h> int main() { pid_t pid = fork(); if (pid == 0) { printf("Child process (PID: %d)\n", getpid()); } else { printf("Parent process (Child PID: %d)\n", pid); } return 0; } -
exec系列 - 执行新程序#include <unistd.h> int execl(const char *path, const char *arg, ...); int execv(const char *path, char *const argv[]); int execle(const char *path, const char *arg, ..., char *const envp[]); int execve(const char *path, char *const argv[], char *const envp[]); int execlp(const char *file, const char *arg, ...); int execvp(const char *file, char *const argv[]);示例:
#include <unistd.h> #include <stdio.h> int main() { char *args[] = {"ls", "-l", NULL}; printf("About to execute ls -l\n"); execvp("ls", args); perror("execvp failed"); return 1; } -
wait/waitpid- 等待子进程状态变化#include <sys/wait.h> pid_t wait(int *status); pid_t waitpid(pid_t pid, int *status, int options);示例:
#include <sys/wait.h> #include <unistd.h> #include <stdio.h> int main() { pid_t pid = fork(); if (pid == 0) { printf("Child process\n"); sleep(2); return 42; } else { int status; waitpid(pid, &status, 0); if (WIFEXITED(status)) { printf("Child exited with status %d\n", WEXITSTATUS(status)); } } return 0; } -
exit/_exit- 终止进程#include <stdlib.h> // exit #include <unistd.h> // _exit void exit(int status); void _exit(int status);示例:
#include <stdlib.h> #include <stdio.h> int main() { printf("Exiting with status 5\n"); exit(5); }
三、进程资源与优先级函数
-
getrlimit/setrlimit- 资源限制#include <sys/resource.h> int getrlimit(int resource, struct rlimit *rlim); int setrlimit(int resource, const struct rlimit *rlim);示例:
#include <sys/resource.h> #include <stdio.h> int main() { struct rlimit lim; getrlimit(RLIMIT_STACK, &lim); printf("Stack size limit: soft=%lu, hard=%lu\n", lim.rlim_cur, lim.rlim_max); return 0; } -
getpriority/setpriority- 进程优先级#include <sys/resource.h> int getpriority(int which, id_t who); int setpriority(int which, id_t who, int prio);示例:
#include <sys/resource.h> #include <stdio.h> int main() { int prio = getpriority(PRIO_PROCESS, 0); printf("Current nice value: %d\n", prio); setpriority(PRIO_PROCESS, 0, 10); // Lower priority return 0; } -
nice- 调整进程优先级#include <unistd.h> int nice(int inc);示例:
#include <unistd.h> #include <stdio.h> int main() { printf("Original nice value: %d\n", nice(0)); nice(5); // Increase nice value (lower priority) printf("New nice value: %d\n", nice(0)); return 0; }
四、进程间通信函数
-
kill- 向进程发送信号#include <signal.h> int kill(pid_t pid, int sig);示例:
#include <signal.h> #include <stdio.h> #include <unistd.h> int main() { pid_t pid = getpid(); printf("Sending SIGUSR1 to myself (PID: %d)\n", pid); kill(pid, SIGUSR1); return 0; } -
pipe- 创建管道#include <unistd.h> int pipe(int pipefd[2]);示例:
#include <unistd.h> #include <stdio.h> #include <string.h> int main() { int fd[2]; pipe(fd); if (fork() == 0) { close(fd[0]); // Close read end const char *msg = "Hello from child!"; write(fd[1], msg, strlen(msg)+1); close(fd[1]); } else { close(fd[1]); // Close write end char buf[100]; read(fd[0], buf, sizeof(buf)); printf("Parent received: %s\n", buf); close(fd[0]); } return 0; }
五、高级进程控制函数
-
clone- 创建轻量级进程#define _GNU_SOURCE #include <sched.h> int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...);示例:
#define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #define STACK_SIZE (1024 * 1024) static int child_func(void *arg) { printf("Child process in new namespace\n"); return 0; } int main() { void *stack = malloc(STACK_SIZE); if (!stack) { perror("malloc"); return 1; } pid_t pid = clone(child_func, stack + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL); if (pid == -1) { perror("clone"); return 1; } waitpid(pid, NULL, 0); free(stack); return 0; }
六、进程信息获取函数
-
sysinfo- 获取系统信息#include <sys/sysinfo.h> int sysinfo(struct sysinfo *info);示例:
#include <sys/sysinfo.h> #include <stdio.h> int main() { struct sysinfo info; sysinfo(&info); printf("Uptime: %ld minutes\n", info.uptime / 60); printf("Total RAM: %lu MB\n", info.totalram / (1024 * 1024)); printf("Free RAM: %lu MB\n", info.freeram / (1024 * 1024)); return 0; } -
sysconf- 获取系统配置信息#include <unistd.h> long sysconf(int name);示例:
#include <unistd.h> #include <stdio.h> int main() { printf("Page size: %ld bytes\n", sysconf(_SC_PAGESIZE)); printf("Number of processors: %ld\n", sysconf(_SC_NPROCESSORS_ONLN)); printf("Max child processes: %ld\n", sysconf(_SC_CHILD_MAX)); return 0; }
七、进程组与会话控制函数
-
setsid- 创建新会话#include <unistd.h> pid_t setsid(void);示例:
#include <unistd.h> #include <stdio.h> int main() { pid_t sid = setsid(); if (sid == -1) { perror("setsid"); return 1; } printf("New session ID: %d\n", sid); return 0; } -
getpgid/setpgid- 进程组控制#include <unistd.h> pid_t getpgid(pid_t pid); int setpgid(pid_t pid, pid_t pgid);示例:
#include <unistd.h> #include <stdio.h> int main() { pid_t pid = fork(); if (pid == 0) { // Child sets itself as group leader setpgid(0, 0); printf("Child PGID: %d\n", getpgid(0)); } else { printf("Parent PGID: %d\n", getpgid(0)); wait(NULL); } return 0; }
八、信号处理函数
-
signal- 设置信号处理#include <signal.h> void (*signal(int signum, void (*handler)(int)))(int);示例:
#include <signal.h> #include <stdio.h> #include <unistd.h> void handler(int sig) { printf("Received signal %d\n", sig); } int main() { signal(SIGUSR1, handler); printf("Waiting for signal... PID=%d\n", getpid()); pause(); // Wait for signal return 0; } -
sigaction- 高级信号处理#include <signal.h> int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);示例:
#include <signal.h> #include <stdio.h> #include <string.h> void handler(int sig, siginfo_t *info, void *context) { printf("Received signal %d from PID %d\n", sig, info->si_pid); } int main() { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_sigaction = handler; sa.sa_flags = SA_SIGINFO; sigaction(SIGUSR1, &sa, NULL); printf("Waiting for signal... PID=%d\n", getpid()); pause(); return 0; }
九、环境变量函数
-
getenv- 获取环境变量#include <stdlib.h> char *getenv(const char *name);示例:
#include <stdlib.h> #include <stdio.h> int main() { char *path = getenv("PATH"); if (path) { printf("PATH: %s\n", path); } return 0; }
十、时间函数
-
times- 获取进程时间#include <sys/times.h> clock_t times(struct tms *buf);示例:
#include <sys/times.h> #include <stdio.h> #include <unistd.h> int main() { struct tms start, end; times(&start); // Do some work for (int i = 0; i < 100000000; i++); times(&end); long clk_tck = sysconf(_SC_CLK_TCK); printf("User time: %.2f seconds\n", (end.tms_utime - start.tms_utime) / (double)clk_tck); return 0; }
十一、/proc 文件系统访问
-
通过标准 I/O 访问 /proc
#include <stdio.h>示例:
#include <stdio.h> int main() { FILE *fp = fopen("/proc/self/status", "r"); if (fp) { char line[256]; while (fgets(line, sizeof(line), fp)) { if (strncmp(line, "VmRSS:", 6) == 0) { printf("Memory usage: %s", line); } } fclose(fp); } return 0; }
十二、进程调度函数
-
sched_getaffinity/sched_setaffinity- CPU 亲和性#define _GNU_SOURCE #include <sched.h> int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask); int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask);示例:
#define _GNU_SOURCE #include <sched.h> #include <stdio.h> int main() { cpu_set_t mask; CPU_ZERO(&mask); CPU_SET(0, &mask); // Use only CPU 0 if (sched_setaffinity(0, sizeof(mask), &mask) == -1) { perror("sched_setaffinity"); return 1; } printf("Process bound to CPU 0\n"); return 0; }
函数总结
这些函数提供了对 Linux 进程管理的全面控制能力:
- 基础操作:
fork,exec,wait,exit - 信息获取:
getpid,getppid,getuid,sysinfo,/proc访问 - 资源控制:
getrlimit,setpriority,nice - 通信与信号:
pipe,kill,signal,sigaction - 高级控制:
clone,setsid,sched_setaffinity
实际使用时,需要根据具体需求选择合适的函数组合,并注意错误处理和权限要求(如设置优先级需要特权)。
更多推荐

所有评论(0)