当前位置: 首页 > news >正文

TLPI 第12章 读书笔记:System and Process Information

笔记和练习博客总目录见:开始读TLPI。

在本章中,我们研究访问各种系统和进程信息的方法。本章的主要重点是讨论 /proc 文件系统。我们还描述了 uname() 系统调用,该调用用于检索各种系统标识符。

12.1 The /proc File System

在早期的 UNIX 实现中,通常没有简便的方法可以自省地分析(或更改)内核的属性,以回答如下问题:

  • 系统上有多少进程在运行,它们的所有者是谁?
  • 一个进程打开了哪些文件?
  • 当前哪些文件被锁定,哪些进程持有这些锁?
  • 系统上使用了哪些套接字?

一些早期的 UNIX 实现通过允许特权程序深入内核内存中的数据结构来解决这个问题。然而,这种方法存在各种问题。特别是,它需要对内核数据结构有专业知识,并且这些结构可能会随内核版本的变化而变化,这就要求依赖这些结构的程序必须被重写。

为了提供更方便的内核信息访问,许多现代 UNIX 实现提供了/proc 虚拟文件系统。该文件系统位于 /proc 目录下,包含各种暴露内核信息的文件,允许进程方便地读取这些信息,并在某些情况下使用普通文件 I/O 系统调用进行更改。/proc 文件系统被称为虚拟文件系统,是因为它包含的文件和子目录并不存储在磁盘上。相反,内核会在进程访问它们时“即时”创建这些文件和目录。

在本节中,我们概述 /proc 文件系统。在后续章节中,我们将描述与每章主题相关的具体 /proc 文件。尽管许多 UNIX 实现提供了 /proc 文件系统,但 SUSv3 并未指定该文件系统;本书描述的细节是特定于 Linux 的。

12.1.1 Obtaining Information About a Process: /proc/PlD

对于系统上的每个进程,内核都会提供一个对应的目录,名为 /proc/PID,其中 PID 是该进程的 ID。在这个目录中有各种文件和子目录,包含关于该进程的信息。例如,我们可以通过查看 /proc/1 目录下的文件来获取关于 init 进程的信息,该进程的进程 ID 始终为 1。

在每个 /proc/PID 目录中的文件中,有一个名为 status 的文件,它提供了关于该进程的一系列信息:

$cat/proc/1/status Name: systemd# Name of command run by this processUmask: 0000 State: S(sleeping)# State of this processTgid:1# Thread group ID (traditional PID, getpid())Ngid:0Pid:1# Actually, thread ID (gettid())PPid:0# Parent process IDTracerPid:0# PID of tracing process (0 if not traced)Uid:0000# Real, effective, saved set, and FS UIDsGid:0000# Real, effective, saved set, and FS GIDsFDSize:128# # of file descriptor slots currently allocatedGroups:# Supplementary group IDsNStgid:1NSpid:1NSpgid:1NSsid:1VmPeak:239548kB# Peak virtual memory sizeVmSize:174012kB# Current virtual memory sizeVmLck:0kB# Locked memoryVmPin:0kB VmHWM:16548kB# Peak resident set sizeVmRSS:16548kB# Current resident set sizeRssAnon:5436kB RssFile:11112kB RssShmem:0kB VmData:21188kB# Data segment sizeVmStk:132kB# Stack sizeVmExe:44kB# Text (executable code) sizeVmLib:12824kB# Shared library code sizeVmPTE:104kB# Size of page table (since 2.6.10)VmSwap:0kB HugetlbPages:0kB CoreDumping:0THP_enabled:1Threads:1# # of threads in this thread’s thread groupSigQ:1/13600# Current/max. queued signals (since 2.6.12)SigPnd: 0000000000000000# Signals pending for threadShdPnd: 0000000000000000# Signals pending for process (since 2.6)SigBlk: 7fe3c0fe28014a03# Blocked signalsSigIgn: 0000000000001000# Ignored signalsSigCgt: 00000001000004ec# Caught signalsCapInh: 0000000000000000# Inheritable capabilitiesCapPrm: 000001ffffffffff# Permitted capabilitiesCapEff: 000001ffffffffff# Effective capabilitiesCapBnd: 000001ffffffffff# Capability bounding set (since 2.6.26)CapAmb: 0000000000000000 NoNewPrivs:0Seccomp:0Seccomp_filters:0Speculation_Store_Bypass: vulnerable SpeculationIndirectBranch: always enabled Cpus_allowed: 1f# CPUs allowed, mask (since 2.6.24)Cpus_allowed_list:0-4# Same as above, list format (since 2.6.26)Mems_allowed: 00000000,...,00000001# Memory nodes allowed, mask (since 2.6.24)Mems_allowed_list:0# Same as above, list format (since 2.6.26)voluntary_ctxt_switches:3800# Voluntary context switches (since 2.6.23)nonvoluntary_ctxt_switches:35000# Involuntary context switches (since 2.6.23)

以上输出来自内核 5.15.0。如伴随该文件输出的备注中所示,该文件的格式随着时间演变,在各个内核版本中添加了新字段(在少数情况下也删除了部分字段)。(除了上文提到的 Linux 2.6 变化外,Linux 2.4 添加了 Tgid、TracerPid、FDSize 和 Threads 字段。)

$cat/proc/version Linux version5.15.0-314.193.5.5.el9uek.x86_64(mockbuild@host-100-100-224-97)(gcc(GCC)11.5.020240719(Red Hat11.5.0-11.0.1), GNU ld version2.35.2-67.0.1.el9)#2 SMP Fri Nov 28 07:05:37 PST 2025

这个文件内容随时间变化的事实提出了一个关于使用 /proc 文件的一般性问题:当这些文件包含多个条目时,我们应该采取防御性解析——在这种情况下,应查找包含特定字符串的行(例如 PPid:)的匹配,而不是按(逻辑)行号处理文件。

表 12-1 列出了每个 /proc/PID目录中发现的一些其他文件。

Table 12-1: Selected files in each /proc/PID directory

FileDescription (process attribute)
cmdlineCommand-line arguments delimited by \0
cwdSymbolic link to current working directory
environEnvironment list NAME=value pairs, delimited by \0
exeSymbolic link to file being executed
fdDirectory containing symbolic links to files opened by this process
mapsMemory mappings
memProcess virtual memory (must lseek() to valid offset before I/O)
mountsMount points for this process
rootSymbolic link to root directory
statusVarious information (e.g., process IDs, credentials, memory usage, signals)
taskContains one subdirectory for each thread in process (Linux 2.6)

The /proc/PID/fd directory
/proc/PID/fd 目录包含该进程打开的每个文件描述符的一个符号链接。每个符号链接的名称与描述符编号相匹配;例如,/proc/1968/1 是进程 1968 的标准输出的符号链接。更多信息,请参阅第 5.11 节。

为了方便,任何进程都可以使用符号链接 /proc/self 访问其自身的 /proc/PID 目录。

$ls/proc/self/fd0123

Threads: the /proc/PID/task directory
Linux 2.4 引入了线程组的概念,以正确支持 POSIX 线程模型。由于线程组中的线程有些属性是不同的,Linux 2.4 在 /proc/PID 目录下添加了一个任务子目录。对于该进程中的每个线程,内核提供一个名为 /proc/PID/task/TID 的子目录,其中 TID 是该线程的线程 ID。(这与在该线程中调用 gettid() 返回的编号相同。)

12.1.2 System Information Under /proc

/proc 下的各种文件和子目录提供了对系统范围信息的访问。下面的图 12-1 显示了一些这些内容。

图 12-1 中显示的许多文件在本书其他地方有描述。表 12-2 总结了图 12-1 中显示的 /proc 子目录的总体用途。

Table 12-2: Purpose of selected /proc subdirectories

DirectoryInformation exposed by files in this directory
/procVarious system information
/proc/netStatus information about networking and sockets
/proc/sys/fsSettings related to file systems
/proc/sys/kernelVarious general kernel settings
/proc/sys/netNetworking and sockets settings
/proc/sys/vmMemory-management settings
/proc/sysvipcInformation about System V IPC objects

12.1.3 Accessing /proc Files

/proc 下的文件通常通过 shell 脚本访问(大多数包含多个值的 /proc 文件可以很容易地使用诸如 Python 或 Perl 之类的脚本语言解析)。例如,我们可以使用 shell 命令修改和查看 /proc 文件的内容,如下所示:

$cat/proc/sys/kernel/pid_max4194304$echo4194303>/proc/sys/kernel/pid_max $cat/proc/sys/kernel/pid_max4194303$echo4194304>/proc/sys/kernel/pid_max

/proc 文件也可以通过程序使用常规文件 I/O 系统调用来访问。访问这些文件时有一些限制:

  • 一些 /proc 文件是只读的;也就是说,它们仅用于显示内核信息,不能用于修改这些信息。这适用于大多数 /proc/PID 目录下的文件。
  • 一些 /proc 文件只能由文件所有者(或特权进程)读取。例如,/proc/PID 下的所有文件都属于拥有相应进程的用户,并且在这些文件中的某些文件(如 /proc/PID/environ),读取权限仅授予文件所有者。
  • 除了 /proc/PID 子目录中的文件外,/proc 下的大多数文件归 root 所有,并且可修改的文件只能由 root 修改。

图略
Figure 12-1: Selected files and subdirectories under /proc

Accessing files in /proc/PID
/proc/PID 目录是易失性的。这些目录中的每一个都会在具有相应进程 ID 的进程创建时出现,并在该进程终止时消失。这意味着,如果我们确定某个特定的 /proc/PID 目录存在,那么当我们试图打开该目录下的某个文件时,需要妥善处理这种情况:即该进程可能已经终止,并且相应的 /proc/PID 目录在我们打开文件之前就已经被删除了。

Example program
清单 12-1 演示了如何读取和修改 /proc 文件。该程序读取并显示 /proc/sys/kernel/pid_max 的内容。如果提供了命令行参数,程序将使用该值更新该文件。此文件(在 Linux 2.6 中新增)指定了进程 ID 的上限(第 6.2 节)。以下是使用该程序的一个示例:

$cat/proc/sys/kernel/pid_max4194304$ ./procfs_pidmax4194304$ ./procfs_pidmax4000000Old value:4194304/proc/sys/kernel/pid_max now contains4000000

Listing 12-1: Accessing /proc/sys/kernel/pid_max

// sysinfo/procfs_pidmax.c// 代码略if(argc>1){if(lseek(fd,0,SEEK_SET)==-1)errExit("lseek");if(write(fd,argv[1],strlen(argv[1]))!=(ssize_t)strlen(argv[1]))fatal("write() failed");...}

💡 /proc文件系统一定不同于一般的文件系统,否则无法理解write一个宽度较小的值何以能覆盖宽度较大的值(或者反之)。因为/proc是一个虚拟文系统,/proc/sys/kernel/pid_max 本质上是一个内核变量接口,不是真正的文件。写入时内核只是从中提取数值,不关心字符串长度是否一致,因此不同长度的字符串完全没问题。

12.2 System Identification: uname()

uname() 系统调用返回关于应用程序运行的主机系统的一系列识别信息,这些信息保存在 utsbuf 指向的结构中。

#include<sys/utsname.h>intuname(structutsname*utsbuf);

utsbuf 参数是指向 utsname 结构的指针,该结构定义如下:

#define_UTSNAME_LENGTH65structutsname{charsysname[_UTSNAME_LENGTH];/* Implementation name */charnodename[_UTSNAME_LENGTH];/* Node name on network */charrelease[_UTSNAME_LENGTH];/* Implementation release level */charversion[_UTSNAME_LENGTH];/* Release version level */charmachine[_UTSNAME_LENGTH];/* Hardware on which system is running */#ifdef_GNU_SOURCE/* Following is Linux-specific */chardomainname[_UTSNAME_LENGTH];/* NIS domain name of host */#endif};

SUSv3 指定了 uname(),但未定义 utsname 结构中各个字段的长度,仅要求字符串以空字节终止。在 Linux 上,这些字段的长度均为 65 字节,包括用于终止空字节的空间。在一些 UNIX 实现中,这些字段较短;在其他实现(例如 Solaris)中,字段长度可达 257 字节。

utsname 结构的 sysname、release、version 和 machine 字段由内核自动设置。

在 Linux 中,目录 /proc/sys/kernel 中的三个文件提供了与 utsname 结构的 sysname、release 和 version 字段返回的信息相同的访问权限。这些只读文件分别是 ostype、osrelease 和 version。另一个文件 /proc/version 包含这些文件中的相同信息,同时还包括关于内核编译步骤的信息(即执行编译的用户名称、进行编译的主机名称以及使用的 gcc 版本)。

nodename 字段返回使用 sethostname() 系统调用设置的值(有关此系统调用的详细信息,请参阅手册页)。通常,这个名字类似于系统 DNS 域名的主机名前缀。

domainname 字段返回使用 setdomainname() 系统调用设置的值(有关此系统调用的详细信息,请参阅手册页)。这是主机的网络信息服务(NIS)域名(这与主机的 DNS 域名不同)。

gethostname() 系统调用是 sethostname() 的反向操作,用于检索系统主机名。系统主机名也可以使用 hostname(1) 命令和 Linux 特有的 /proc/hostname 文件进行查看和设置。

getdomainname() 系统调用是 setdomainname() 的反向操作,用于检索 NIS 域名。NIS 域名也可以使用 domainname(1) 命令和 Linux 特有的 /proc/domainname 文件进行查看和设置。

sethostname() 和 setdomainname() 系统调用在应用程序中很少使用。通常,主机名和 NIS 域名在启动时由启动脚本设置。

清单 12-2 中的程序显示了 uname() 返回的信息。运行该程序时,我们可能会看到如下示例输出:

$ ./t_uname Node name: ol9-vagrant System name: Linux Release:5.15.0-314.193.5.5.el9uek.x86_64 Version:#2 SMP Fri Nov 28 07:05:37 PST 2025Machine: x86_64 Domain name:(none)

Listing 12-2: Using uname()

// sysinfo/t_uname.c// 代码略

12.3 Summary

/proc 文件系统向应用程序公开了一系列内核信息。每个 /proc/PID 子目录包含提供与 PID 匹配的进程信息的文件和子目录。/proc 下的其他各种文件和目录公开系统范围的信息,程序可以读取这些信息,并且在某些情况下,可以修改这些信息。

uname() 系统调用允许我们发现 UNIX 的实现以及应用程序运行的机器类型。

Further information
关于 /proc 文件系统的更多信息可以在 proc(5) 手册页、内核源文件 Documentation/filesystems/proc.txt 中以及 Documentation/sysctl 目录中的各种文件中找到。

12.4 Exercises

参见TLPI 第12章 练习:System and Process Information。

http://www.jsqmd.com/news/699265/

相关文章:

  • ARMv8架构PLB与RAS机制解析及优化实践
  • 2026北京高考冲刺一对一,如何选到梦中情班? - 品牌测评鉴赏家
  • 2026届毕业生推荐的十大AI写作工具横评
  • 如何将酷我音乐KWM格式转换为MP3?详细步骤与工具推荐
  • OpenCV图像特征提取:边缘与角点检测实战指南
  • intv_ai_mk11镜像免配置:健康检查接口+日志路径固化+服务状态可视
  • 【MCP 2026工业落地实战白皮书】:覆盖钢铁、能源、制造三大高危场景的7类适配陷阱与零故障部署清单
  • 【限时开放】VSCode 2026农业插件Early Access权限倒计时48小时:含独家GeoJSON农田边界自动校准模块(仅剩217个激活码)
  • 读2025世界前沿技术发展报告51干细胞
  • 智能安防中的视频分析与预警处置
  • 别再手动轮询了!用STM32CubeMX+DMA搞定ADC多通道采样,效率提升不止一点点
  • 【工业级MCP网关配置白皮书】:基于Linux内核4.19+DPDK 22.11的C++实现,含6份可审计配置清单
  • 软考-数据库系统工程师-五大经典查找算法原理与数据库应用
  • Phi-4-mini-reasoning部署案例:边缘服务器(Jetson AGX Orin)可行性评估
  • DeepTutor:基于智能体原生架构的个性化AI学习伴侣部署与实战指南
  • Ubuntu 安装CUDA 教程
  • 董永建《信息学奥赛一本通》(C++版)
  • 量化不确定性的庖丁解牛
  • 大数据分析专业毕设京东美妆产品数据集,数据量大概32150条
  • 【VSCode 2026日志筛选分析工具终极指南】:20年一线工程师亲测的5大高阶技巧,90%开发者还不知道
  • 游戏电竞护航陪玩源码系统小程序:从多端接单到俱乐部级运营的全开源护航平台 - 壹软科技
  • GoWxDump:如何快速实现微信聊天记录的深度取证分析?
  • MT5 Zero-Shot中文增强镜像效果展示:直播话术实时多样性生成
  • 避坑+自救:智能仓储物流项目烂尾的6个典型场景,附复活实战思路
  • Keras实战:构建Seq2Seq机器翻译模型
  • ROS小车CAN通信实战:从DBC文件到socketcan_bridge消息收发的避坑指南
  • KoboldAI终极指南:三步打造你的专属AI写作助手
  • 2026年长沙短视频运营与GEO豆包AI推广避坑指南:5大服务商深度横评 - 年度推荐企业名录
  • 如何用MAA助手彻底解放双手:明日方舟智能辅助的完整指南
  • 开源自建博客的天花板!一款轻量级、高性能、高安全性的博客网站,3步搭建个人博客平台