System and Process Information

/proc 文件系统

该文件系统驻留于 /proc 目录中,包含了各种用于展示内核信息的文件,并且允许进程通过常规文件 I/O 系统调用来方便地读取,有时还可以修改这些信息。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 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: 128
Groups:
NStgid: 1
NSpid:  1
NSpgid: 1
NSsid:  1
VmPeak:   312064 kB
VmSize:   246528 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:     11112 kB
VmRSS:      8368 kB
RssAnon:            2912 kB
RssFile:            5456 kB
RssShmem:              0 kB
VmData:    27180 kB
VmStk:       132 kB
VmExe:      1288 kB
VmLib:     16316 kB
VmPTE:       224 kB
VmSwap:        0 kB
HugetlbPages:          0 kB
CoreDumping:    0
Threads:        1
SigQ:   4/7192
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 7be3c0fe28014a03
SigIgn: 0000000000001000
SigCgt: 00000001800004ec
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
NoNewPrivs:     0
Seccomp:        0
Speculation_Store_Bypass:       vulnerable
Cpus_allowed:   1
Cpus_allowed_list:      0
Mems_allowed:   00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list:      0
voluntary_ctxt_switches:        30378015
nonvoluntary_ctxt_switches:     44011

获取与进程有关的信息: /proc/PID/

文件 描述(进程属性)
cmdline \0分隔的命令行参数
cwd 指向当前工作目录的符号链接
Environ NAME=value 键值对环境列表,以\0分隔
exe 指向正在执行文件的符号链接
fd 文件目录,包含了指向由进程打开文件的符号链接
maps 内存映射
mem 进程虚拟内存(在 I/O 操作前必须调用 lseek()移至有效偏移量)
mounts 进程的挂载点
root 指向根目录的符号链接
status 各种信息(进程 ID、凭证、内存使用量、信号)
task 为进程中的每个线程均包含一个子目录

针对进程中的每个线程,内核提供了以/proc/PID/task/TID命名的子目录,其中 TID 时该线程的线程 ID。

/proc 下的系统信息

/proc 目录下的各种文件和子目录提供了对系统级信息的访问。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <fcntl.h>
#include "tlpi_hdr.h"

#define MAX_LINE 100

int main(int argc, char *argv[])
{
    int fd;
    char line[MAX_LINE];
    ssize_t n;

    fd = open("/proc/sys/kernel/pid_max", (argc > 1) ? O_RDWR : O_RDONLY);
    if (fd == -1)
    {
        errExit("open");
    }

    n = read(fd, line, MAX_LINE);
    if (n == -1)
    {
        errExit("read");
    }
    if (argc > 1)
    {
        printf("Old value: ");
    }
    printf("%.*s", (int)n, line);
    if (argc > 1)
    {
        if (lseek(fd, 0, SEEK_SET) == -1)
        {
            errExit("lseek");
        }
        if (write(fd, argv[1], strlen(argv[1])) != strlen(argv[1]))
        {
            fatal("write() failed");
        }
        system("echo /proc/sys/kernel/pid_max now contains "
               "`cat /proc/sys/kernel/pid_max`");
    }
    exit(EXIT_SUCCESS);
}

系统标识 uname()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <sys/utsname.h>

int uname(struct utsname *utsbuf);

/* Structure describing the system and machine.  */
struct utsname
  {
    /* Name of the implementation of the operating system.  */
    char sysname[_UTSNAME_SYSNAME_LENGTH];

    /* Name of this node on the network.  */
    char nodename[_UTSNAME_NODENAME_LENGTH];

    /* Current release level of this implementation.  */
    char release[_UTSNAME_RELEASE_LENGTH];
    /* Current version level of this release.  */
    char version[_UTSNAME_VERSION_LENGTH];

    /* Name of the hardware type the system is running on.  */
    char machine[_UTSNAME_MACHINE_LENGTH];

#if _UTSNAME_DOMAIN_LENGTH - 0
    /* Name of the domain of this node on the network.  */
# ifdef __USE_GNU
    char domainname[_UTSNAME_DOMAIN_LENGTH];
# else
    char __domainname[_UTSNAME_DOMAIN_LENGTH];
# endif
  };

uname 返回了一系列关于主机系统的标志信息,存储于 utsbuf 所指向的结构。【utsname 结构中 sysname, release, version, machine 字段由内核自动设置】

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifdef __linux__
#define _GNU_SOURCE
#endif
#include <sys/utsname.h>
#include "tlpi_hdr.h"

int main(int argc, char *argv[])
{
    struct utsname uts;

    if (uname(&uts) == -1)
        errExit("uname");

    printf("Node name:   %s\n", uts.nodename);
    printf("System name: %s\n", uts.sysname);
    printf("Release:     %s\n", uts.release);
    printf("Version:     %s\n", uts.version);
    printf("Machine:     %s\n", uts.machine);
#ifdef _GNU_SOURCE
    printf("Domain name: %s\n", uts.domainname);
#endif
    exit(EXIT_SUCCESS);
}
Licensed under CC BY-NC-SA 4.0
Get Things Done
Built with Hugo
Theme Stack designed by Jimmy