ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Linux 任务管理深度实操:从进程查看到 cgroups 资源控制

Linux 任务管理深度实操:从进程查看到 cgroups 资源控制 Linux 任务管理深度实操从进程查看到 cgroups 资源控制服务器环境: Ubuntu 24.04.4 LTS, 内核 6.8.0-106-generic, x86_64实操时间: 2026-09-08核心目标: 在真实服务器上全面实践 Linux 任务管理的各个方面包括进程查看、状态分析、进程创建、线程管理、优先级控制、CPU 亲和性、信号机制、资源限制、cgroups 和进程关系。前言Linux 任务管理是系统管理员和开发者的核心技能。从理解进程的诞生与消亡到精确控制资源分配每一个环节都直接影响系统的稳定性和性能。本文在一台真实的 Ubuntu 24.04 服务器上通过实际命令操作和 C 程序演示带你深入理解 Linux 任务管理的方方面面。一、进程查看ps 命令的三种视角1.1ps aux—— BSD 风格的进程快照ps aux是最常用的进程查看命令a表示所有进程u表示以用户友好格式输出x表示包括没有控制终端的进程。psaux|head-30实际输出USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 22536 13944 ? Ss 21:35 0:02 /sbin/init noibrs root 2 0.0 0.0 0 0 ? S 21:35 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S 21:35 0:00 [pool_workqueue_release] root 4 0.0 0.0 0 0 ? I 21:35 0:00 [kworker/R-rcu_g] root 5 0.0 0.0 0 0 ? I 21:35 0:00 [kworker/R-rcu_p] root 6 0.0 0.0 0 0 ? I 21:35 0:00 [kworker/R-slub_] root 7 0.0 0.0 0 0 ? I 21:35 0:00 [kworker/R-netns] root 10 0.0 0.0 0 0 ? I 21:35 0:00 [kworker/0:0H-events_highpri] root 12 0.0 0.0 0 0 ? I 21:35 0:00 [kworker/R-mm_pe] root 13 0.0 0.0 0 0 ? I 21:35 0:00 [rcu_tasks_kthread] root 14 0.0 0.0 0 0 ? I 21:35 0:00 [rcu_tasks_rude_kthread] root 15 0.0 0.0 0 0 ? I 21:35 0:00 [rcu_tasks_trace_kthread] root 16 0.0 0.0 0 0 ? S 21:35 0:00 [ksoftirqd/0] root 17 0.0 0.0 0 0 ? I 21:35 0:00 [rcu_preempt] root 18 0.0 0.0 0 0 ? S 21:35 0:00 [migration/0] root 19 0.0 0.0 0 0 ? S 21:35 0:00 [idle_inject/0] root 20 0.0 0.0 0 0 ? S 21:35 0:00 [cpuhp/0]关键字段解读PID: 进程 ID系统唯一标识%CPU / %MEM: CPU 和内存使用率VSZ: 虚拟内存大小KBRSS: 物理内存使用量KBSTAT: 进程状态详见下文TTY: 控制终端?表示无终端1.2ps -ef—— System V 风格ps -ef展示父子进程关系-e表示所有进程-f表示完整格式。ps-ef|head-30实际输出UID PID PPID C STIME TTY TIME CMD root 1 0 0 21:35 ? 00:00:02 /sbin/init noibrs root 2 0 0 21:35 ? 00:00:00 [kthreadd] root 3 2 0 21:35 ? 00:00:00 [pool_workqueue_release] root 4 2 0 21:35 ? 00:00:00 [kworker/R-rcu_g] root 5 2 0 21:35 ? 00:00:00 [kworker/R-rcu_p] root 6 2 0 21:35 ? 00:00:00 [kworker/R-slub_] root 7 2 0 21:35 ? 00:00:00 [kworker/R-netns] root 10 2 0 21:35 ? 00:00:00 [kworker/0:0H-events_highpri] root 13 2 0 21:35 ? 00:00:00 [rcu_tasks_kthread] root 16 2 0 21:35 ? 00:00:00 [ksoftirqd/0] root 17 2 0 21:35 ? 00:00:00 [rcu_preempt] root 18 2 0 21:35 ? 00:00:00 [migration/0]这里最关键的是PPID父进程 ID。可以看到 PID 1systemd的 PPID 为 0而所有内核线程的 PPID 都是 2kthreadd。1.3ps -eLf—— 查看线程级信息-L参数显示每个线程LWP轻量级进程的信息ps-eLf|head-30实际输出UID PID PPID LWP C NLWP STIME TTY TIME CMD root 1 0 1 0 1 21:35 ? 00:00:02 /sbin/init noibrs root 2 0 2 0 1 21:35 ? 00:00:00 [kthreadd] root 3 2 3 0 1 21:35 ? 00:00:00 [pool_workqueue_release]LWP: 线程 ID轻量级进程 IDNLWP: 该进程拥有的线程数量二、进程状态深度解析2.1 /proc/[pid]/status 详解每个进程在/proc文件系统中都有一个目录其中status文件包含进程的详细信息。cat/proc/1/status实际输出Name: systemd Umask: 0000 State: S (sleeping) Tgid: 1 Ngid: 0 Pid: 1 PPid: 0 TracerPid: 0 Uid: 0 0 0 0 Gid: 0 0 0 0 FDSize: 256 Groups: NStgid: 1 NSpid: 1 NSpgid: 1 NSsid: 1 Kthread: 0 VmPeak: 23276 kB VmSize: 22536 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 13944 kB VmRSS: 13944 kB RssAnon: 4308 kB RssFile: 9636 kB RssShmem: 0 kB VmData: 3504 kB VmStk: 132 kB VmExe: 44 kB VmLib: 12196 kB VmPTE: 84 kB VmSwap: 0 kB HugetlbPages: 0 kB CoreDumping: 0 THP_enabled: 1 Threads: 1 SigQ: 1/60201 Cpus_allowed: ff Cpus_allowed_list: 0-7 voluntary_ctxt_switches: 2656 nonvoluntary_ctxt_switches: 3682.2 进程状态分类通过统计当前系统所有进程的状态可以直观看到各状态的分布psaux|awk{print $8}|sort|uniq-c|sort-rn实际输出62 S 50 I 29 I 12 Ss 10 Ssl 2 Ss 2 SN 2 Sl 1 STAT 1 Ss 1 SLsl 1 RLinux 进程状态一览状态码含义说明RRunning正在运行或在运行队列中等待SSleeping可中断睡眠等待事件发生DDisk sleep不可中断睡眠通常在等待 I/OZZombie僵尸进程已终止但未被父进程回收TTraced/Stopped被信号停止或被追踪IIdle空闲状态内核线程附加标志高优先级N低优先级s会话首进程l多线程前台进程组三、top 与 htop实时进程监控3.1 top 命令top-bn1|head-25实际输出top - 22:33:19 up 58 min, 1 user, load average: 0.00, 0.00, 0.00 Tasks: 169 total, 1 running, 168 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st MiB Mem : 15131.8 total, 14356.9 free, 533.3 used, 512.5 buff/cache MiB Swap: 0.0 total, 0.0 free, 0.0 used. 14598.5 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND 1 root 20 0 22536 13944 9636 S 0.0 0.1 0:02.11 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd 3 root 20 0 0 0 0 S 0.0 0.0 0:00.00 pool_wo 4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker 18 root rt 0 0 0 0 S 0.0 0.0 0:00.00 migrati 19 root -51 0 0 0 0 S 0.0 0.0 0:00.00 idle_intop 输出关键信息Tasks: 169 个进程1 个运行168 个睡眠0 个僵尸PR: 优先级rt表示实时优先级NI: nice 值-20 到 19VIRT/RES/SHR: 虚拟/物理/共享内存3.2 htop 安装与使用apt-getinstall-yhtophtop--version实际输出htop 3.3.0htop 提供了比 top 更友好的交互式界面支持鼠标操作、颜色标记、树状视图等。四、进程创建fork/exec/wait 系统调用4.1 C 程序演示#includestdio.h#includestdlib.h#includeunistd.h#includesys/wait.h#includesys/types.h#includestring.hintmain(){pid_tpid;intstatus;printf(Parent process (PID: %d, PPID: %d) started\n,getpid(),getppid());pidfork();if(pid0){perror(fork failed);exit(1);}elseif(pid0){// Child processprintf(Child process (PID: %d, PPID: %d) - executing ls via execvp\n,getpid(),getppid());char*args[]{ls,-la,/tmp,NULL};execvp(ls,args);perror(execvp failed);exit(1);}else{// Parent processprintf(Parent (PID: %d) waiting for child (PID: %d)...\n,getpid(),pid);waitpid(pid,status,0);if(WIFEXITED(status)){printf(Child exited with status: %d\n,WEXITSTATUS(status));}printf(Parent process finished\n);}return0;}4.2 编译与运行gcc-ofork_demo fork_demo.c ./fork_demo实际输出total 1864 drwxrwxrwt 15 root root 4096 Sep 8 22:33 . drwxr-xr-x 24 root root 4096 Sep 8 21:35 .. -rwx------ 1 root root 1783080 Sep 8 21:35 CmsSignatureVerify- drwxrwxrwt 2 root root 4096 Sep 8 21:35 .font-unix -rwxr-xr-x 1 root root 16360 Sep 8 22:33 fork_demo -rw-r--r-- 1 root root 965 Sep 8 22:33 fork_demo.c ... Parent process (PID: 8947, PPID: 8801) started Parent (PID: 8947) waiting for child (PID: 8948)... Child exited with status: 0 Parent process finishedfork/exec/wait 三件套解析fork(): 创建子进程返回值 0 表示子进程正数表示子进程 PID在父进程中exec(): 替换当前进程映像PID 不变但代码段被新程序替换wait(): 父进程等待子进程结束回收资源避免僵尸进程五、线程管理pthread5.1 多线程 C 程序#includestdio.h#includestdlib.h#includepthread.h#includeunistd.h#includestring.hvoid*thread_func(void*arg){intthread_num*(int*)arg;printf(Thread %d: TID%lu, PID%d\n,thread_num,(unsignedlong)pthread_self(),getpid());sleep(1);printf(Thread %d: exiting\n,thread_num);returnNULL;}intmain(){pthread_tthreads[3];intthread_args[3]{1,2,3};printf(Main thread: PID%d, TID%lu\n,getpid(),(unsignedlong)pthread_self());for(inti0;i3;i){if(pthread_create(threads[i],NULL,thread_func,thread_args[i])!0){perror(pthread_create failed);exit(1);}printf(Created thread %d\n,i1);}for(inti0;i3;i){pthread_join(threads[i],NULL);}printf(All threads joined. Main thread exiting.\n);return0;}5.2 编译与运行gcc-opthread_demo pthread_demo.c-lpthread./pthread_demo实际输出Main thread: PID8955, TID135622234765120 Created thread 1 Thread 1: TID135622230537920, PID8955 Created thread 2 Thread 2: TID135622222145216, PID8955 Created thread 3 Thread 3: TID135622213752512, PID8955 Thread 1: exiting Thread 2: exiting Thread 3: exiting All threads joined. Main thread exiting.关键观察所有线程共享同一个 PID8955但每个线程有独立的 TID。在 Linux 中线程本质上是通过clone()系统调用创建的轻量级进程LWP可以通过/proc/[pid]/task/目录查看。六、进程优先级nice / renice / chrt6.1 nice 值nice 值范围是 -20最高优先级到 19最低优先级默认为 0。nice# 查看当前 nice 值renice5-p$$# 将当前进程 nice 值设为 5renice0-p$$# 恢复为 0实际输出0 8930 (process ID) old priority 0, new priority 5 8930 (process ID) old priority 5, new priority 06.2 实时调度策略chrtchrt-p1实际输出pid 1s current scheduling policy: SCHED_OTHER pid 1s current scheduling priority: 0Linux 调度策略SCHED_OTHER(0): 默认分时调度优先级 0SCHED_FIFO(1): 实时先进先出优先级 1-99SCHED_RR(2): 实时轮转优先级 1-99SCHED_BATCH(3): 批处理调度SCHED_IDLE(5): 空闲调度七、CPU 亲和性tasksetCPU 亲和性控制进程可以在哪些 CPU 核心上运行。taskset-p1cat/proc/1/status|grepCpus实际输出pid 1s current affinity mask: ff Cpus_allowed: ff Cpus_allowed_list: 0-7ff是二进制掩码表示 PID 1systemd可以在 CPU 0-7 上运行8 核服务器。通过taskset可以绑定进程到特定核心taskset-c0,1./my_program# 绑定到 CPU 0 和 1八、进程信号机制8.1 信号列表kill-l实际输出1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN1 ... 64) SIGRTMAX常用信号速查信号编号含义可否捕获SIGHUP1挂起常用于重载配置✅SIGINT2中断CtrlC✅SIGKILL9强制杀死❌SIGTERM15优雅终止✅SIGSTOP19停止❌SIGCONT18继续✅SIGCHLD17子进程状态变化✅九、进程资源限制ulimit 与 /proc/[pid]/limits9.1 ulimit 命令ulimit-a实际输出real-time non-blocking time (microseconds, -R) unlimited core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 60201 max locked memory (kbytes, -l) 1936876 max memory size (kbytes, -m) unlimited open files (-n) 65535 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 60201 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited9.2 /proc/[pid]/limitscat/proc/1/limits实际输出Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 8388608 unlimited bytes Max core file size 0 unlimited bytes Max resident set unlimited unlimited bytes Max processes 60201 60201 processes Max open files 1048576 1048576 files Max locked memory 1983361024 1983361024 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 60201 60201 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited usSoft Limit是当前生效的限制Hard Limit是上限。进程可以通过setrlimit()系统调用调整 soft limit但不能超过 hard limit。十、cgroups控制组资源隔离10.1 查看已注册的 cgroup 子系统cat/proc/cgroups实际输出#subsys_name hierarchy num_cgroups enabled cpuset 0 110 1 cpu 0 110 1 cpuacct 0 110 1 blkio 0 110 1 memory 0 110 1 devices 0 110 1 freezer 0 110 1 net_cls 0 110 1 perf_event 0 110 1 net_prio 0 110 1 hugetlb 0 110 1 pids 0 110 1 rdma 0 110 1 misc 0 110 110.2 cgroup v2 文件系统ls/sys/fs/cgroup/mount|grepcgroup实际输出cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)目录内容包含cgroup.controllers、cpu.stat、memory.pressure等控制文件以及system.slice、user.slice等子组。10.3 创建 cgroup 限制 CPU# 创建 cgroupmkdir-p/sys/fs/cgroup/demo_group# 设置 CPU 限制每 100ms 中允许使用 50ms CPU 时间50%echo50000 100000/sys/fs/cgroup/demo_group/cpu.max# 验证cat/sys/fs/cgroup/demo_group/cpu.max# 清理rmdir/sys/fs/cgroup/demo_group实际输出Created cgroup 50000 100000 cleanup done50000 100000表示在每 100000 微秒100ms的周期内该 cgroup 中的进程最多可以使用 50000 微秒50ms的 CPU 时间即限制为 50% CPU。十一、进程关系父子进程、进程组与会话11.1 进程层次结构ps-ejH|head-30实际输出PID PGID SID TTY TIME CMD 2 0 0 ? 00:00:00 kthreadd 3 0 0 ? 00:00:00 pool_workqueue_release 4 0 0 ? 00:00:00 kworker/R-rcu_g 5 0 0 ? 00:00:00 kworker/R-rcu_p 16 0 0 ? 00:00:00 ksoftirqd/0 18 0 0 ? 00:00:00 migration/011.2 进程树视图pstree|head-30实际输出systemd--HSSInstall---sleep |-ModemManager---3*[{ModemManager}] |-NetworkManager---3*[{NetworkManager}] |-2*[agetty] |-chronyd---chronyd |-cron |-dbus-daemon |-fwupd---5*[{fwupd}] |-irqbalance---{irqbalance} |-multipathd---6*[{multipathd}] |-polkitd---3*[{polkitd}] |-rsyslogd---3*[{rsyslogd}] |-sshd---sshd---bash--head | -pstree |-systemd---(sd-pam) |-systemd-journal |-systemd-logind |-systemd-resolve |-systemd-udevd |-udisksd---5*[{udisksd}] |-unattended-upgr---{unattended-upgr} |-uniagent---6*[{uniagent}] |-uniagentd--sh---uniagentd---3*[{uniagentd}] | -sh---uniagentd---5*[{uniagentd}] |-upowerd---3*[{upowerd}] -wpa_supplicant11.3 进程组与会话ps-eopid,ppid,pgid,sid,comm|head-20实际输出PID PPID PGID SID COMMAND 1 0 1 1 systemd 2 0 0 0 kthreadd 3 2 0 0 pool_workqueue_release 4 2 0 0 kworker/R-rcu_g 16 2 0 0 ksoftirqd/0 18 2 0 0 migration/0三个层次的关系进程: 最小执行单元有唯一 PID进程组 (PGID): 相关进程的集合便于批量信号发送会话 (SID): 进程组的集合通常关联一个终端十二、C 程序使用 syslog() 函数#includestdio.h#includesyslog.h#includeunistd.hintmain(){openlog(demo_app,LOG_PID|LOG_NDELAY,LOG_LOCAL0);syslog(LOG_EMERG,EMERG message (level 0): system is unusable);syslog(LOG_ALERT,ALERT message (level 1): action must be taken immediately);syslog(LOG_CRIT,CRIT message (level 2): critical conditions);syslog(LOG_ERR,ERR message (level 3): error conditions);syslog(LOG_WARNING,WARNING message (level 4): warning conditions);syslog(LOG_NOTICE,NOTICE message (level 5): normal but significant);syslog(LOG_INFO,INFO message (level 6): informational);syslog(LOG_DEBUG,DEBUG message (level 7): debug-level messages);printf(Messages sent to syslog. Check with: journalctl -t demo_app\n);closelog();return0;}编译运行后通过journalctl查看日志gcc-osyslog_demo syslog_demo.c ./syslog_demo journalctl-tdemo_app --no-pager-n10实际输出Sep 08 22:33:24 ecs-e349-f33a-0004 demo_app[8965]: EMERG message (level 0): system is unusable Sep 08 22:33:24 ecs-e349-f33a-0004 demo_app[8965]: ALERT message (level 1): action must be taken immediately Sep 08 22:33:24 ecs-e349-f33a-0004 demo_app[8965]: CRIT message (level 2): critical conditions Sep 08 22:33:24 ecs-e349-f33a-0004 demo_app[8965]: ERR message (level 3): error conditions Sep 08 22:33:24 ecs-e349-f33a-0004 demo_app[8965]: WARNING message (level 4): warning conditions Sep 08 22:33:24 ecs-e349-f33a-0004 demo_app[8965]: NOTICE message (level 5): normal but significant Sep 08 22:33:24 ecs-e349-f33a-0004 demo_app[8965]: INFO message (level 6): informational Sep 08 22:33:24 ecs-e349-f33a-0004 demo_app[8965]: DEBUG message (level 7): debug-level messages总结本文在真实的 Ubuntu 24.04 服务器上全面实操了 Linux 任务管理的核心知识进程查看掌握了ps aux、ps -ef、ps -eLf三种视角理解了 BSD 和 System V 风格的差异进程状态通过/proc/[pid]/status深入理解了 R/S/D/Z/T/I 六种状态及其含义实时监控使用top和htop监控系统进程状态进程创建通过 C 程序演示了fork()/exec()/wait()三件套的工作流程线程管理使用pthread创建多线程程序理解了 Linux 线程与进程的关系优先级控制通过nice/renice/chrt控制进程调度优先级CPU 亲和性使用taskset绑定进程到特定 CPU 核心信号机制了解了 64 种信号的用途和特性资源限制通过ulimit和/proc/[pid]/limits查看和设置资源上限cgroups在 cgroup v2 中创建控制组并限制 CPU 资源进程关系理解了进程、进程组、会话三个层次的组织结构这些知识是 Linux 系统管理和性能调优的基础掌握它们将帮助你更好地理解和控制 Linux 系统的行为。
返回列表