【Linux应用编程】系统信息与资源 | 如获取、设置系统时间、日期、/proc 虚拟文件系统等

系统信息与系统资源

  • 通过 Linux 系统调用或 C 库函数获取系统信息(如获取系统时间、日期以及设置系统时间、日期等);

  • Linux 系统下的/proc 虚拟文件系统(读取系统、进程有关信息);


系统信息

主要介绍了用于获取系统相关信息的函数;

  • uname:用于获取有关当前操作系统内核的名称和信息;

  • sysinfo :获取一些系统统计信息

  • gethostname :单独获取 Linux 系统主机名,与 struct utsname 数据结构体中 nodename 变量一样;

  • sysconf:运行时获取系统的一些配置信息

系统标识 uname
  • uname()用于获取有关当前操作系统内核的名称和信息;
原型
/*man 2 uname*/
#include <sys/utsname.h>
int uname(struct utsname *buf);
/*
参数:buf:struct utsname 结构体类型指针,指向一个 struct utsname 结构体类型对象
返回值:成功返回 0;失败将返回-1,并设置 errno。
*/
用法

先定义一个 struct utsname 结构体变量,调用 uname()函数时传入变量的地址即可;

结构:struct utsname 结构体中的所有成员变量都是字符数组,所以获取到的信息都是字符串

						/*示例代码 7.1.1 struct utsname 结构体*/
struct utsname {char sysname[]; 		/* 当前操作系统的名称 */char nodename[]; 		/* 网络上的名称(主机名) */char release[]; 		/* 操作系统内核版本 */char version[]; 		/* 操作系统发行版本 */char machine[]; 		/* 硬件架构类型 */#ifdef _GNU_SOURCEchar domainname[];		/* 当前域名 */#endif
};
测试

获取并打印出当前操作系统名称、主机名、内核版本、操作系统发行版本以及处理器硬件架构类型等信息;

示例代码 7.1.2 uname 函数使用示例
#include <stdio.h>
#include <stdlib.h>
#include <sys/utsname.h>
int main(void)
{struct utsname os_info;int ret;/* 获取信息 */ret = uname(&os_info);if (-1 == ret) {perror("uname error");exit(-1);}/* 打印信息 */printf("操作系统名称: %s\n", os_info.sysname);printf("主机名: %s\n", os_info.nodename);printf("内核版本: %s\n", os_info.release);printf("发行版本: %s\n", os_info.version);printf("硬件架构: %s\n", os_info.machine);exit(0);
}
函数 sysinfo
  • 用于获取一些系统统计信息
原型
#include <sys/sysinfo.h>
int sysinfo(struct sysinfo *info);
/*
参数:info:struct sysinfo 结构体类型指针,指向一个 struct sysinfo 结构体类型对象。
返回值:成功返回 0;失败将返回-1,并设置 errno
用法

先定义一个 struct sysinfo 结构体变量,调用 sysinfo()函数时传入变量的地址即可;

函数 gethostname
  • 用于单独获取 Linux 系统主机名,与 struct utsname 数据结构体中的 nodename 变量一样;
原型
#include <unistd.h>
int gethostname(char *name, size_t len);
/*
参数:name:指向用于存放主机名字符串的缓冲区。len:缓冲区长度。
返回值:成功返回 0;失败将返回-1,并会设置 errno
用法
					/*示例代码 7.1.5 gethostname 函数获取系统主机名使用示例*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(void)
{char hostname[20];int ret;memset(hostname, 0x0, sizeof(hostname));ret = gethostname(hostname, sizeof(hostname));if (-1 == ret) {perror("gethostname error");exit(ret);}puts(hostname);exit(0);
}
函数sysconf

运行时获取系统的一些配置信息

/*获取配置信息:页大小(page size)、主机名最大长度、进程可打开的最大文件数、ID 的最大并发进程数等*/
#include <unistd.h>
long sysconf(int name)//参数 name 指定要获取哪个配置信息,参数 name 可取以下任何一个值(都是宏定义,可通过 man 手册查询)

时间、日期

介绍下时间、日期相关的系统调用或 C 库函数以及它们的使用方法;

时间概念
时间

GMT(Greenwich Mean Time)时间:格林威治标准时间;

UTC(Coordinated Universal Time):世界协调时间;

在 Ubuntu 系统下,可以使用"date -u"命令查看到当前的 UTC 时间;“date "	命令查看系统当前的本地时间;
时区

时区信息通常以标准格式保存在一些通常位于/usr/share/zoneinfo目录文件(时区配置文件)当中;

典例

修改 Ubuntu 系统本地时间的时区信息;

sudo rm -rf localtime 							#删除原有链接文件
sudo ln -s /usr/share/zoneinfo/EST localtime 	#重新建立链接文件

再使用 date 命令查看下系统当前的时间:

在这里插入图片描述

Linux 系统中的时间
点时间和段时间

字面意思略

实时RTC和系统时钟
  • 操作系统中一般会有两个时钟,系统时钟(system clock)和 实时时钟(Real time clock),也叫 RTC;

  • 开机:系统时钟

  • 关机:实时时钟(一般由 RTC 时钟芯片提供,自带电池,关机维护)

Linux 系统记录时间
  • Linux 系统在开机启动之后首先会读取 RTC 硬件获取实时时钟作为系统时钟的初始值;

  • 随之内核便开始维护自己的系统时钟。所以RTC 硬件只有在系统开机启动时会读取一次(初始化);

  • 系统关机时,内核会将系统时钟写入到 RTC 硬件、已进行同步操作;

获取时间函数

通过 time()或 gettimeofday()函数对jiffies进行换算,可以获取到当前时间点相对于 1970-01-01 00:00:00 +0000 (UTC)这个时间点所经过时间(日历时间),所以获取得到的是一个时间段的长度

jiffies引入

在这里插入图片描述

time 函数
  • 系统调用 time()用于获取当前时间,以秒为单位;
原型
#include <time.h>
time_t time(time_t *tloc);
/*
参数:tloc:如果 tloc 参数不是 NULL,则返回值也存储在 tloc 指向的内存中。
返回值:成功则返回自 1970-01-01 00:00:00 +0000 (UTC)以来的时间值(以秒为单位);失败则返回-1,并会设置 errno
gettimeofday()函数
  • 提供微秒级时间精度;
原型
#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);
/*
参数:tv:参数tv是一个struct timeval结构体指针变量,struct timeval已介绍,参考示例 5.6.3。tz:调gettimeofday()函数时应将参数 tz 设置为 NULL。
返回值:成功返回 0;失败将返回-1,并设置 errno。获取得到的时间值存储在参数 tv 所指向的 struct timeval 结构体变量中,该结构体包含了两个成员变量tv_sec 和 tv_usec,分别用于表示秒和微秒,所以获取得到的时间值就是 tv_sec(秒)+tv_usec(微秒),同样获取得到的秒数与 time()函数一样,也是自 1970-01-01 00:00:00 +0000 (UTC)到现在这段时间所经过的秒数,也就是日历时间,所以由此可知 time()返回得到的值和函数 gettimeofday()所返回的 tv 参数中 tv_sec 字段的数值相同。
时间转换函数

介绍一些系统调用或 C 库函数,通过这些 API 可以将 time()或 gettimeofday()函数获取到的秒数转换为利于查看和理解的形式;

ctime 函数
  • 将日历时间转换为可打印输出的字符串形式
原型
#include <time.h>
char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);
/*
参数:timep:time_t 时间变量指针。
返回值:成功将返回一个 char *类型指针,指向转换后得到的字符串;失败将返回 NULL。
localtime 函数
  • 把 time()或 gettimeofday()得到的秒数(time_t 时间或日历时间)变成一个 struct tm结构体所表示的时间,该时间对应的是本地时间;
原型
#include <time.h>
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);
/*
参数:timep:	需进行转换的 time_t 时间变量对应指针,可通过 time()或 gettimeofday()获取得到;result:	struct tm 结构体类型指针,稍后介绍 struct tm 结构体,参数 result 是可重入函数localtime_r()需要额外提供的参数.
返回值:对于不可重入版本 localtime()来说,成功则返回一个有效的 struct tm 结构体指针,而对于可重入版本 localtime_r()来说,成功执行情况下,返回值将会等于参数 result;失败则返回 NULL.
gmtime 函数
  • gmtime()函数也可以把 time_t 时间变成一个 struct tm 结构体所表示的时间

  • 与 localtime()所不同:gmtime()函数所得到的是 UTC 国际标准时间,并不是计算机的本地时间;

原型
#include <time.h>
struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);
/*
gmtime_r()是 gmtime()的可重入版本,同样推荐使用可重入版本函数 gmtime_r。
该函数的参数和返回值,与 localtime()一样;
mktime 函数
  • mktime()与 localtime()相反,mktime()将使用 struct tm 结构体表示的分解时间转换为 time_t时间(日历时间);
原型
#include <time.h>
time_t mktime(struct tm *tm);
/*
参数:tm:需要进行转换的 struct tm 结构体变量对应的指针。
返回值:成功返回转换得到 time_t 时间值;失败返回-1。
asctime 函数
  • asctime()函数与 ctime()函数的作用一样,也可将时间转换为可打印输出的字符串形式;

  • 与 ctime()函数的区别:ctime()是将 time_t 时间转换为固定格式字符串、而 asctime()则是将 struct tm 表示的分解时间转换为固定格式的字符串

原型
#include <time.h>
char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *tm, char *buf);
/*
参数:tm:需要进行转换的 struct tm 表示的时间。buf:可重入版本 asctime_r 需要额外提供的参数 buf,指向一个缓冲区,用于存放转换得到的字符串。
返回值:转换失败将返回 NULL;成功将返回一个 char *类型指针,指向转换后得到的时间字符串;对于 asctime_r 函数来说,返回值就等于参数 buf。
trftime 函数
  • 可以将一个 struct tm 变量表示的分解时间转换为为格式化字符串;

  • 它可以根据自己的喜好自定义时间的显示格式,而 asctime()和 ctime()得到字符串格式固定;

原型
#include <time.h>
size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
/*
参数:s:		指向一个缓存区的指针,该缓冲区用于存放生成的字符串。max:	字符串的最大字节数;format:	一个用字符串表示的字段,包含了普通字符和特殊格式说明符,可以是这两种字符的任意组合。tm:		指向 struct tm 结构体对象的指针。
返回值:如果转换得到的目标字符串不超过最大字节数(也就是 max),则返回放置到 s 数组中的字节数;如果超过了最大字节数,则返回 0。

特殊格式说明符将会被替换为 struct tm 结构体对象所指时间的相应值,这些特殊格式说明符如下

在这里插入图片描述

设置时间 settimeofday

可以设置时间,也就是设置系统的本地时间;

原型
#include <sys/time.h>
int settimeofday(const struct timeval *tv, const struct timezone *tz);
/*
参数下:tv:参数 tv 是一个 struct timeval 结构体指针变量,struct timeval 结构体前已介绍;需要设置的时间便通过参数 tv 指向的 struct timeval 结构体变量传递进去;tz:调用 settimeofday()函数时应将参数 tz 设置为 NULL;
返回值:成功返回 0;失败将返回-1,并设置 errno。

使用 settimeofday 设置系统时间只有超级用户(root)才可以设置系统时间,普通用户将无操作权限。

总结

介 绍 了 Linux 系 统 下 常 用 的 时 间 相 关 的 系 统 调 用 和 库 函 数;

time/ctime/localtime/gmtime/mktime/asctime/strftime/gettimeofday/settimeofday

在这里插入图片描述


进程时间

  • 进程时间指的是进程从创建后(也就是程序运行后)到目前为止这段时间内使用 CPU 资源的时间总数,出于记录的目的;

  • 进程时间 = 用户 CPU 时间 + 系统 CPU 时间 :

  • 用户 CPU 时间:进程在用户空间(用户态)下运行所花费的 CPU 时间。有时也成为虚拟时间;

  • 系统 CPU 时间:进程在内核空间(内核态)下运行所花费的 CPU 时间。这是内核执行系统调用或

    代表进程执行的其它任务(譬如,服务页错误)所花费的时间。

    Tips:进程时间不等于程序的整个生命周期所消耗的时间,如果进程一直处于休眠状态(进程被挂起、
    不会得到系统调度),那么它并不会使用 CPU 资源,所以休眠的这段时间并不计算在进程时间中.
    
struct tms 结构体
					/*示例代码 7.3.1 struct tms 结构体*/
struct tms {clock_t tms_utime; 	/* user time, 进程的用户 CPU 时间, tms_utime 个系统节拍数 */clock_t tms_stime; 	/* system time, 进程的系统 CPU 时间, tms_stime 个系统节拍数 */clock_t tms_cutime; 	/* user time of children:已死掉子进程的 tms_utime + tms_cutime时间总和 */clock_t tms_cstime; 	/* system time of children:已死掉子进程的 tms_stime + tms_cstime 时间总和 */
};
times 函数
  • 用于获取当前进程时间
原型
#include <sys/times.h>
clock_t times(struct tms *buf);
/*
参数:buf:times()会将当前进程时间信息存在一个 struct tms 结构体数据中,所以我们需要提供 struct tms 变量,使用参数 buf 指向该变量;返回值:返回值类型为 clock_t(实质是 long 类型),调用成功情况下,将返回从过去任意的一个时间点(譬如系统启动时间)所经过的时钟滴答数(其实就是系统节拍数),将(节拍数 / 节拍率)便可得到秒数,返回值可能会超过 clock_t 所能表示的范围(溢出);调用失败返回-1,并设置 errno。如果我们想查看程序运行到某一个位置时的进程时间,或者计算出程序中的某一段代码执行过程所花费的进程时间,都可以使用 times()函数来实现
实例

times()来计算程序中某一段代码执行所耗费的进程时间和总的时间;

示例代码 7.3.2 times 函数使用示例
#include <stdio.h>
#include <stdlib.h>
#include <sys/times.h>
#include <unistd.h>
int main(int argc, char *argv[])
{struct tms t_buf_start;struct tms t_buf_end;clock_t t_start;clock_t t_end;long tck;int i, j;/* 获取系统的节拍率 */tck = sysconf(_SC_CLK_TCK);/* 开始时间 */t_start = times(&t_buf_start);if (-1 == t_start) {perror("times error");exit(-1);}/* *****需要进行测试的代码段***** */for (i = 0; i < 20000; i++)for (j = 0; j < 20000; j++);sleep(1); //休眠挂起/* *************end************** *//* 结束时间 */t_end = times(&t_buf_end);if (-1 == t_end) {perror("times error");exit(-1);}/* 打印时间 */printf("时间总和: %f 秒\n", (t_end - t_start) / (double)tck);printf("用户 CPU 时间: %f 秒\n", (t_buf_end.tms_utime - t_buf_start.tms_utime) / (double)tck);printf("系统 CPU 时间: %f 秒\n", (t_buf_end.tms_stime - t_buf_start.tms_stime) / (double)tck);exit(0);
}

程序中使用 sysconf(_SC_CLK_TCK)获取到系统节拍率,程序还使用了一个库函数 sleep();

在这里插入图片描述

可以看到用户 CPU 时间为 1.9 秒,系统 CPU 时间为 0 秒,也就是说测试的这段代码并没有进入内核态运行,所以总的进程时间 = 用户 CPU 时间 + 系统 CPU 时间 = 1.9 秒;

显示的时间总和并不是总的进程时间!

clock 函数
  • 提供了一个更为简单的方式用于进程时间,它的返回值描述了进程使用的总的 CPU 时间(也就是进程时间,包括用户 CPU 时间和系统 CPU 时间);

  • clock()函数虽然可以很方便的获取总的进程时间,但并不能获取到单独的用户 CPU 时间和系统 CPU 时间,在实际编程当中,根据自己的需要选择;

原型
#include <time.h>
clock_t clock(void);
/*
参数:无参数.
返回值:返回值是到目前为止程序的进程时间,为 clock_t 类型,注意 clock()的返回值并不是系统节拍数;如果想要获得秒数,请除以 CLOCKS_PER_SEC(这是一个宏);如果返回的进程时间不可用或其值无法表示,则该返回值是-1.
实例

对示例代码 7.3.2 进行简单地修改,使用 clock()获取到待测试代码段所消耗的进程时间

						/*示例代码 7.3.3 clock 函数使用示例*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{clock_t t_start;clock_t t_end;int i, j;/* 开始时间 */t_start = clock();if (-1 == t_start)exit(-1);/* *****需要进行测试的代码段***** */for (i = 0; i < 20000; i++)for (j = 0; j < 20000; j++);/* *************end************** *//* 结束时间 */t_end = clock();if (-1 == t_end)exit(-1);/* 打印时间 */printf("总的 CPU 时间: %f\n", (t_end - t_start) / (double)CLOCKS_PER_SEC);exit(0);
}

在这里插入图片描述


产生随机数

  • 随机数是随机出现,没有任何规律的一组数列;

  • 编程当中说到的随机数,基本都是指伪随机数;

  • C 语言函数库中常用 rand()和 srand()产生随机数;

rand 函数
  • 用于获取随机数,多次调用 rand()可得到一组随机数序列;
原型
#include <stdlib.h>
int rand(void);
/*
返回值:返回一个介于 0 到 RAND_MAX(包含)之间的值,也就是数学上的[0, RAND_MAX]。
srand 函数
  • 使用 srand()函数为 rand()设置随机数种子
  • 常用的用法:
    srand(time(NULL));
原型
#include <stdlib.h>
void srand(unsigned int seed);
/*
参数:seed:指定一个随机数中,int 类型的数据,一般尝尝将当前时间作为随机数种子赋值给参数 seed;譬如 time(NULL),因为每次启动应用程序时间上是一样的;所以就能够使得程序中设置的随机数种子在每次启动程序时是不一样的.
返回值:void
常用的用法:srand(time(NULL));
实例

使用 rand()和 srand()产生一组伪随机数,数值范围为[0~100],将其打印出来;

					/*示例代码 7.4.1 生成随机数示例代码*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{int random_number_arr[8];int count;/* 设置随机数种子 */srand(time(NULL));/* 生成伪随机数 */for (count = 0; count < 8; count++)random_number_arr[count] = rand() % 100;/* 打印随机数数组 */printf("[");for (count = 0; count < 8; count++) {printf("%d", random_number_arr[count]);if (count != 8 - 1)printf(", ");}printf("]\n");exit(0);
}

在这里插入图片描述

每一次得到的[0~100]之间的随机数数组都是不同的(数组不同,不是产生的随机数不同),因为程序中将 rand()的随机数种子设置为 srand(time(NULL)),直接等于 time_t 时间值,意味着每次启动种子都不一样,所以能够产生不同的随机数数组;

还有 random()、srandom()、initstate()、setstate()等;


休眠

  • 有时需要将进程暂停或休眠一段时间,进入休眠状态之后,程序将暂停运行,直到休眠结束;

  • 常用的C 库函数有 sleep()、usleep(),系统调用 nanosleep(),应用程序当中通常作为延时使用;

秒级休眠: sleep
  • sleep()是一个秒级别休眠函数,程序在休眠过程中,是可以被其它信号所打断;
原型
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
/*
参数:seconds:休眠时长,以秒为单位.
返回值:如果休眠时长为参数 seconds 所指定的秒数,则返回 0;若被信号中断则返回剩余的秒数.
微秒级休眠: usleep
原型
#include <unistd.h>
int usleep(useconds_t usec);
/*
参数:usec:休眠时长,以微秒为单位.
返回值:成功返回 0;失败返回-1,并设置 errno.
使用实例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{puts("Sleep Start1!");/* 让程序休眠 3 秒钟 */sleep(3);puts("Sleep End1!");puts("Sleep Start2!");/* 让程序休眠 3 秒钟(3*1000*1000 微秒) */usleep(3 * 1000 * 1000);puts("Sleep End2!");exit(0);
}
高精度休眠: nanosleep
  • 具有更高精度来设置休眠时间长度,支持纳秒级时长设置,为系统调用
原型
#include <time.h>
int nanosleep(const struct timespec *req, struct timespec *rem);
/*
参数:req:一个 struct timespec 结构体指针,指向一个 struct timespec 变量,用于设置休眠时间长度,可精确
到纳秒级别。rem:也是一个 struct timespec 结构体指针,指向一个 struct timespec 变量,也可设置 NULL。
返回值:在成功休眠达到请求的时间间隔后,nanosleep()返回 0;如果中途被信号中断或遇到错误,则返回-1;并将剩余时间记录在参数 rem 指向的 struct timespec 结构体变量中;参数 rem 不为 NULL 的情况下,如果为 NULL 表示不接收剩余时间,能设置 errno 标识错误类型。
实例
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{struct timespec request_t;puts("Sleep Start!");/* 让程序休眠 3 秒钟 */request_t.tv_sec = 3;request_t.tv_nsec = 0;nanosleep(&request_t, NULL);puts("Sleep End!");exit(0);
}

申请堆内存

  • 操作系统下,内存资源是由操作系统进行管理、分配的;

  • 当应用程序想要内存(堆内存)时,可以向操作系统申请内存,然后使用内存;

  • 当不再需要时,将申请的内存释放、归还给操作系统;

  • 在许多的应用程序当中,往往都会有这种需求,譬如为一些数据结构动态分配/释放内存空间;

堆上分配内存:malloc&free
  • 使用 malloc()函数为程序分配一段堆内存,而使用 free()函数来释放这段内存;
malloc

malloc()在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被
初始化,它们的值是未知的,所以通常需要程序员对 malloc()分配的堆内存进行初始化操作;

原型
#include <stdlib.h>
void *malloc(size_t size);
/*
参数:size:需要分配的内存大小,以字节为单位。
返回值:返回值为 void *类型;如果申请分配内存成功,将返回一个指向该段内存的指针,void *并不是说没有返回值或者返回空指针,而是返回的指针类型未知,所以在调用 malloc()时通常需要进行强制类型转换,将 void *指针类型转换成我们希望的类型;如果分配内存失败(譬如系统堆内存不足)将返回 NULL;如果参数 size 为 0,返回值也是 NULL.
free

在堆上分配的内存,需要开发者自己手动释放掉,通常使用 free()函数释放堆内存;

原型
#include <stdlib.h>
void free(void *ptr);
/*
参数:ptr:指向需要被释放的堆内存对应的指针.
返回值:无返回值.
实例
					/*示例代码 7.6.1 malloc()和 free()申请/释放堆内存*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MALLOC_MEM_SIZE (1 * 1024 * 1024)
int main(int argc, char *argv[])
{char *base = NULL;/* 申请堆内存 */base = (char *)malloc(MALLOC_MEM_SIZE);if (NULL == base) {printf("malloc error\n");exit(-1);}/* 初始化申请到的堆内存 */memset(base, 0x0, MALLOC_MEM_SIZE);/* 使用内存 *//* ...... *//* 释放内存 */free(base);exit(0);
}

调用 free()还是不调用 free()

在这里插入图片描述

其它方法
calloc()分配内存

在这里插入图片描述

分配对齐内存

常用分配对其内存的库函数:posix_memalign()、aligned_alloc()、memalign()、valloc()、pvalloc()

#include <stdlib.h>int posix_memalign(void **memptr, size_t alignment, size_t size);
void *aligned_alloc(size_t alignment, size_t size);
void *valloc(size_t size);
#include <malloc.h>
void *memalign(size_t alignment, size_t size);
void *pvalloc(size_t size);

函数不再详细赘述,详细可查看stdlib库;

proc 文件系统

简介

在这里插入图片描述

/proc 目录下中包含了一些目录和虚拟文件,如下所示:

在这里插入图片描述

可以看到/proc 目录下有很多以数字命名的文件夹,譬如 100038、2299、98560,这些数字对应的其实是一个一个的进程 PID 号,每一个进程在内核中都会存在一个编号,通过此编号来区分不同的进程,这个编号就是 PID 号,关于 PID、以及进程相关的信息;

这些以数字命名的文件夹中记录了这些进程相关的信息,不同的信息通过不同的虚拟文件呈现出来;

/proc 目录下除了文件夹之外,还有很多的虚拟文件,譬如 buddyinfo、cgroups、cmdline、version 等等,不同的文件记录了不同信息,关于这些文件记录的信息和意思如下:

⚫ cmdline:内核启动参数;

⚫ cpuinfo:CPU 相关信息;

⚫ iomem:IO 设备的内存使用情况;

⚫ interrupts:显示被占用的中断号和占用者相关的信息;

⚫ ioports:IO 端口的使用情况;

⚫ kcore:系统物理内存映像,不可读取;

⚫ loadavg:系统平均负载;

⚫ meminfo:物理内存和交换分区使用情况;

⚫ modules:加载的模块列表;

⚫ mounts:挂载的文件系统列表;

⚫ partitions:系统识别的分区表;

⚫ swaps:交换分区的利用情况;

⚫ version:内核版本信息;

⚫ uptime:系统运行时间;

proc 文件系统的使用

使用 cat 命令读取:

cat /proc/version

调用 open()打开、然后再使用 read()函数读取:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[])
{char buf[512] = {0};int fd;int ret;/* 打开文件 */fd = open("/proc/version", O_RDONLY);if (-1 == fd) {perror("open error");exit(-1);}/* 读取文件 */ret = read(fd, buf, sizeof(buf));if (-1 == ret) {perror("read error");exit(-1);}/* 打印信息 */puts(buf);/* 关闭文件 */close(fd);exit(0);
}

ne、version 等等,不同的文件记录了不同信息,关于这些文件记录的信息和意思如下:

⚫ cmdline:内核启动参数;

⚫ cpuinfo:CPU 相关信息;

⚫ iomem:IO 设备的内存使用情况;

⚫ interrupts:显示被占用的中断号和占用者相关的信息;

⚫ ioports:IO 端口的使用情况;

⚫ kcore:系统物理内存映像,不可读取;

⚫ loadavg:系统平均负载;

⚫ meminfo:物理内存和交换分区使用情况;

⚫ modules:加载的模块列表;

⚫ mounts:挂载的文件系统列表;

⚫ partitions:系统识别的分区表;

⚫ swaps:交换分区的利用情况;

⚫ version:内核版本信息;

⚫ uptime:系统运行时间;

proc 文件系统的使用

使用 cat 命令读取:

cat /proc/version

调用 open()打开、然后再使用 read()函数读取:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[])
{char buf[512] = {0};int fd;int ret;/* 打开文件 */fd = open("/proc/version", O_RDONLY);if (-1 == fd) {perror("open error");exit(-1);}/* 读取文件 */ret = read(fd, buf, sizeof(buf));if (-1 == ret) {perror("read error");exit(-1);}/* 打印信息 */puts(buf);/* 关闭文件 */close(fd);exit(0);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/379059.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

成都亚恒丰创教育科技有限公司 【插画猴子:笔尖下的灵动世界】

在浩瀚的艺术海洋中&#xff0c;每一种创作形式都是人类情感与想象力的独特表达。而插画&#xff0c;作为这一广阔领域中的璀璨明珠&#xff0c;以其独特的视觉语言和丰富的叙事能力&#xff0c;构建了一个又一个令人遐想连篇的梦幻空间。成都亚恒丰创教育科技有限公司 在众多插…

数据采集监控平台:挖掘数据价值 高效高速生产!

在当今数字化的时代&#xff0c;数据已成为企业非常宝贵的资产之一。然而&#xff0c;要充分发挥数据的潜力&#xff0c;离不开一个强大的数据采集监控平台&#xff0c;尤其是生产制造行业。它不仅是数据的收集者&#xff0c;更是洞察生产的智慧之眼&#xff0c;高效高速处理产…

昇思MindSpore学习开始

昇思MindSpore是一个全场景深度学习框架&#xff0c;旨在实现易开发、高效执行、全场景统一部署三大目标。 其中&#xff0c;易开发表现为API友好、调试难度低&#xff1b;高效执行包括计算效率、数据预处理效率和分布式训练效率&#xff1b;全场景则指框架同时支持云、边缘以…

stm32:CAN通讯

目录 介绍 协议层 CAN的 帧/报文 种类 数据帧 远程帧&#xff08;遥控帧&#xff09; 错误帧 过载帧 帧间隔 总线仲裁 stm32的CAN外设 工作模式 测试模式 功能框图 时序 标准时序 例子 环回静默模式测试 寄存器代码 HAL版本 介绍 一种功能丰富的车用总线标…

基于JAVA+SpringBoot+Vue+uniapp+协同过滤算法+爬虫+AI的减肥小程序

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 小程序用户登录&#…

Guava LocalCache源码分析:LocalCache的get、put、expand、refresh、remove、clear、cleanUp(一)

Guava LocalCache源码分析&#xff1a;LocalCache的get、put、expand 前言一、get二、put三、expand相关链接 前言 上篇文章&#xff0c;详细描写了Guava LocalCache怎样如ConcurrentHashMap对缓存数据进行了分段存储。本章主要针对LocalCache重要的几个接口进行说明。 一、g…

GuLi商城-商品服务-API-属性分组-分组修改级联选择器回显

前端代码:略 后端回显接口: 递归方法: @Override publi

docker部署canal 并监听mysql

1.部署mysql 需要开启mysql的binlong&#xff0c;和创建好用户等 可以参考这个 Docker部署Mysql数据库详解-CSDN博客 2.部署canal 参考这一篇&#xff1a; docker安装Canal&#xff0c;开启MySQL binlog &#xff0c;连接Java&#xff0c;监控MySQL变化_docker canal-CSD…

深入理解JS中的事件委托

JavaScript中的事件委托是一种非常有用的事件处理模式,它允许我们利用事件模型的事件冒泡阶段来减少事件处理器的数量,提高网页性能。本文将介绍事件委托的概念、工作原理、优点以及如何在实际项目中应用事件委托。 1、事件模型 事件模型指在Web开发中,处理和管理事件(如…

分布式对象存储minio

本教程minio 版本&#xff1a;RELEASE.2021-07-*及以上 1. 分布式文件系统应用场景 互联网海量非结构化数据的存储需求 电商网站&#xff1a;海量商品图片视频网站&#xff1a;海量视频文件网盘 : 海量文件社交网站&#xff1a;海量图片 1.1 Minio介绍 MinIO 是一个基于Ap…

通用图形处理器设计GPGPU基础与架构(二)

一、前言 本系列旨在介绍通用图形处理器设计GPGPU的基础与架构&#xff0c;因此在介绍GPGPU具体架构之前&#xff0c;需要了解GPGPU的编程模型&#xff0c;了解软件层面是怎么做到并行的&#xff0c;硬件层面又要怎么配合软件&#xff0c;乃至定出合适的架构来实现软硬件协同。…

最新版智能修图-中文luminar ai 1.55(13797) 和 neo1.20,支持m芯片和intel芯片(绝对可用)

一。Luminar AI for macOS 完整版本 这个程序是第一个完全由人工智能驱动的图像编辑器。有了它&#xff0c;创建引人注目的照片是有趣的&#xff0c;令人惊讶的容易。它是一个独立的照片编辑器和macOS插件。 1.1 Luminar AI for macOS 轻轻地塑造和完善一个肖像打造富有表现…

如何使用 GraalVM 减少与 Kafka 集成测试中的内存消耗

在本文中&#xff0c;我想分享我使用 GraalVM 为 EmbeddedKafka 创建本机映像的经验。在集成测试中使用此映像不仅可以加快测试场景的执行速度&#xff0c;还可以减少内存消耗。有趣的是&#xff0c;与在 Testcontainers 中使用 confluentinc/cp-kafka 相比&#xff0c;在速度和…

VRRP虚拟路由冗余技术

VRRP虚拟路由冗余技术&#xff1a;是一种路由容错协议&#xff0c;用于在网络中提供路由器的冗余备份。它通过将多个路由器虚拟成一个虚拟路由器并且多个路由器之间共享一个虚拟IP地址来实现冗余和高可用性。当承担转发业务的主路由器出现故障时&#xff0c;其他备份路由器可以…

uniapp 微信默认地图选点功能实现

效果图 配置项 微信公众平台-小程序配置 uniapp配置 上代码 <template><view class"content"><button click"toMap">请选择位置</button></view> </template><script setup lang"ts">function toMa…

C# 各版本语法新功能汇总

C# 8.0 以后 官网 C# 7.3 》》in C# 7.2 》》 命名参数、具名参数 》》》 条件 ref 表达式 C# 7.1 》》 default 运算符 default 在C#7.1中得到了改进&#xff0c;不再需要default&#xff08;T&#xff09;了 //变量赋值C#7.0 var s "字符串"; s default(s…

使用llama.cpp量化模型

文章目录 概要整体实验流程技术细节小结 概要 大模型量化是指在保持模型性能尽可能不变的情况下&#xff0c;通过减少模型参数的位数来降低模型的计算和存储成本。本次实验环境为魔搭社区提供的免费GPU环境&#xff08;24G&#xff09;&#xff0c;使用Llama.cpp进行4bit量化可…

前端书籍翻页效果

目录 前端书籍翻页效果前言代码示例创建模板页面css样式编写js代码 结论 前端书籍翻页效果 前端实现翻书效果&#xff0c;附带vue源码 源码下载地址 前言 实际业务开发中&#xff0c;有时候会遇到需要在前端页面内实现翻书效果的需求&#xff0c;本篇文章就为大家介绍如何使…

N Puzzle (数字推盘游戏)

N Puzzle [数字推盘游戏] 1. 15 Puzzle2. N PuzzleReferences puzzle /ˈpʌzl/&#xff1a;n. 谜&#xff0c;智力游戏&#xff0c;疑问&#xff0c;不解之谜&#xff0c;令人费解的事 vt. 迷惑&#xff0c;使困惑1. 15 Puzzle https://en.wikipedia.org/wiki/15_puzzle The…

C#开发:Git的安装和使用

一、安装git 二、如何克隆代码&#xff1f; 1.找到某个本地目录&#xff0c;右键-gitbash 2. 输入以下命令&#xff08;红色是地址&#xff0c;在gitlab获取或联系管理员获取&#xff0c;下图为复制地址的方式&#xff09;&#xff1a; git clone http://xxxxxxxxx.git 输入帐…