Linux应用编程(系统信息与系统资源)

news2024/12/23 2:06:55

在应用程序当中,有时往往需要去获取到一些系统相关的信息,譬如时间、日期、以及其它一些系统相关信息,本章将向大家介绍如何通过 Linux 系统调用或 C 库函数获取系统信息,譬如获取系统时间、日期以及设置系统时间、日期等;除此之外,还会向大家介绍 Linux 系统下的/proc 虚拟文件系统,包括/proc 文件系统是什么以及如何从/proc 文件系统中读取系统、进程有关信息。

除了介绍系统信息内容外,本章还会向大家介绍有关系统资源的使用,譬如系统内存资源的申请与使用等。

一、系统信息

1.1、系统标识 uname

系统调用 uname()用于获取有关当前操作系统内核的名称和信息

#include <sys/utsname.h>
int uname(struct utsname *buf);

函数参数和返回值含义如下:
buf:struct utsname 结构体类型指针,指向一个 struct utsname 结构体类型对象。
返回值:成功返回 0;失败将返回-1,并设置 errno。

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

测试

#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);
}

在这里插入图片描述

1.2、sysinfo 函数

sysinfo 系统调用可用于获取一些系统统计信息

#include <sys/sysinfo.h>
int sysinfo(struct sysinfo *info);

函数参数和返回值含义如下:
info:struct sysinfo 结构体类型指针,指向一个 struct sysinfo 结构体类型对象。
返回值:成功返回 0;失败将返回-1,并设置 errno。

struct sysinfo {
	 long uptime; /* 自系统启动之后所经过的时间(以秒为单位) */
	 unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
	 unsigned long totalram; /* 总的可用内存大小 */
	 unsigned long freeram; /* 还未被使用的内存大小 */
	 unsigned long sharedram; /* Amount of shared memory */
	 unsigned long bufferram; /* Memory used by buffers */
	 unsigned long totalswap; /* Total swap space size */
	 unsigned long freeswap; /* swap space still available */
	 unsigned short procs; /* 系统当前进程数量 */
	 unsigned long totalhigh; /* Total high memory size */
	 unsigned long freehigh; /* Available high memory size */
	 unsigned int mem_unit; /* 内存单元大小(以字节为单位) */
	 char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding to 64 bytes */
};

测试

#include <stdio.h>
#include <stdlib.h>
#include <sys/sysinfo.h>
int main(void)
{
	 struct sysinfo sys_info;
	 int ret;
	 /* 获取信息 */
	 ret = sysinfo(&sys_info);
	 if (-1 == ret) {
		 perror("sysinfo error");
		 exit(-1);
	 }
	 /* 打印信息 */
	 printf("uptime: %ld\n", sys_info.uptime);
	 printf("totalram: %lu\n", sys_info.totalram);
	 printf("freeram: %lu\n", sys_info.freeram);
	 printf("procs: %u\n", sys_info.procs);
	 exit(0);
}

在这里插入图片描述

1.3、gethostname 函数

#include <unistd.h>
int gethostname(char *name, size_t len);

函数参数和返回值含义如下:
name:指向用于存放主机名字符串的缓冲区。
len:缓冲区长度。
返回值:成功返回 0,;失败将返回-1,并会设置 errno。

1.4、sysconf()函数
sysconf()函数是一个库函数,可在运行时获取系统的一些配置信息,譬如页大小(page size)、主机名的最大长度、进程可以打开的最大文件数、每个用户 ID 的最大并发进程数等。

#include <unistd.h>
long sysconf(int name);

使用示例

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
	 printf("每个用户的最大并发进程数: %ld\n", sysconf(_SC_CHILD_MAX));
	 printf("系统节拍率: %ld\n", sysconf(_SC_CLK_TCK));
	 printf("系统页大小: %ld\n", sysconf(_SC_PAGESIZE));
	 exit(0);
}

二、时间、日期

1.1、获取时间 time/gettimeofday

(1)time 函数

系统调用 time()用于获取当前时间,以秒为单位,返回得到的值是自 1970-01-01 00:00:00 +0000 (UTC)以来的秒数

#include <time.h>
time_t time(time_t *tloc);

函数参数和返回值含义如下:
tloc:如果 tloc 参数不是 NULL,则返回值也存储在 tloc 指向的内存中。
返回值:成功则返回自 1970-01-01 00:00:00 +0000 (UTC)以来的时间值(以秒为单位);失败则返回-1,并会设置 errno。

测试

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
	 time_t t;
	 t = time(NULL);
	 if (-1 == t) {
		 perror("time error");
		 exit(-1);
	 }
	 printf("时间值: %ld\n", t);
	 exit(0);
}

在这里插入图片描述
(2)gettimeofday 函数

time()获取到的时间只能精确到秒,如果想要获取更加精确的时间可以使用系统调用 gettimeofday 来实现,gettimeofday()函数提供微秒级时间精度。

#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);

测试

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

int main(void)
{
	 struct timeval tval;
	 int ret;
	 ret = gettimeofday(&tval, NULL);
	 if (-1 == ret) {
		 perror("gettimeofday error");
		 exit(-1);
	 }
	 printf("时间值: %ld 秒+%ld 微秒\n", tval.tv_sec, tval.tv_usec);
	 exit(0);
}

在这里插入图片描述
1.2、时间转换函数

(1)ctime 函数

#include <time.h>
char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);

函数参数和返回值含义如下:
timep:time_t 时间变量指针。
返回值:成功将返回一个 char *类型指针,指向转换后得到的字符串;失败将返回 NULL。

测试

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
	 char tm_str[100] = {0};
	 time_t tm;
	 /* 获取时间 */
	 tm = time(NULL);
	 
	 if (-1 == tm) 
	 {
		 perror("time error");
		 exit(-1);
	 }
	 /* 将时间转换为字符串形式 */
	 ctime_r(&tm, tm_str);
	 /* 打印输出 */
	 printf("当前时间: %s", tm_str);
	 exit(0);
}

在这里插入图片描述
(2)localtime 函数

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。

struct tm {
	 int tm_sec; /* 秒(0-60) */
	 int tm_min; /* 分(0-59) */
	 int tm_hour; /* 时(0-23) */
	 int tm_mday; /* 日(1-31) */
	 int tm_mon; /* 月(0-11) */
	 int tm_year; /* 年(这个值表示的是自 1900 年到现在经过的年数) */
	 int tm_wday; /* 星期(0-6, 星期日 Sunday = 0、星期一=1…) */
	 int tm_yday; /* 一年里的第几天(0-365, 1 Jan = 0) */
	 int tm_isdst; /* 夏令时 */
};

测试

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
	 struct tm t;
	 time_t sec;
	 /* 获取时间 */
	 sec = time(NULL);
	 if (-1 == sec) 
	 {
		 perror("time error");
		 exit(-1);
	 }
	 /* 转换得到本地时间 */
	 localtime_r(&sec, &t);
	 /* 打印输出 */
	 printf("当前时间: %d 年%d 月%d 日 %d:%d:%d\n",t.tm_year + 1900, t.tm_mon, t.tm_mday,t.tm_hour, t.tm_min, t.tm_sec);
	 exit(0);
}

在这里插入图片描述

(3)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()是一样的。

测试

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
	 struct tm local_t;
	 struct tm utc_t;
	 time_t sec;
	 /* 获取时间 */
	 sec = time(NULL);
	 if (-1 == sec) 
	 {
		 perror("time error");
		 exit(-1);
	 }
	 /* 转换得到本地时间 */
	 localtime_r(&sec, &local_t);
	 /* 转换得到国际标准时间 */
	 gmtime_r(&sec, &utc_t);
	 /* 打印输出 */
	 printf("本地时间: %d 年%d 月%d 日 %d:%d:%d\n",local_t.tm_year + 1900, local_t.tm_mon, local_t.tm_mday,local_t.tm_hour, local_t.tm_min, local_t.tm_sec);
	 printf("UTC 时间: %d 年%d 月%d 日 %d:%d:%d\n",utc_t.tm_year + 1900, utc_t.tm_mon, utc_t.tm_mday,utc_t.tm_hour, utc_t.tm_min, utc_t.tm_sec);
	 exit(0);
} 

在这里插入图片描述
(4)mktime 函数

mktime()函数与 localtime()函数相反,mktime()可以将使用 struct tm 结构体表示的分解时间转换为 time_t时间(日历时间),同样这也是一个 C 库函数,其函数原型如下所示:

#include <time.h>
time_t mktime(struct tm *tm);

函数参数和返回值含义如下:
tm:需要进行转换的 struct tm 结构体变量对应的指针。
返回值:成功返回转换得到 time_t 时间值;失败返回-1。

测试

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
	 struct tm local_t;
	 time_t sec;
	 /* 获取时间 */
	 sec = time(NULL);
	 if (-1 == sec) 
	 {
		 perror("time error");
		 exit(-1);
	 }
	 printf("获取得到的秒数: %ld\n", sec);
	 localtime_r(&sec, &local_t);
	 printf("转换得到的秒数: %ld\n", mktime(&local_t));
	 exit(0);
}

在这里插入图片描述
(5)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。

测试

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
	 struct tm local_t;
	 char tm_str[100] = {0};
	 time_t sec;
	 /* 获取时间 */
	 sec = time(NULL);
	 if (-1 == sec) 
	 {
		 perror("time error");
		 exit(-1);
	 }
	 localtime_r(&sec, &local_t);
	 asctime_r(&local_t, tm_str);
	 printf("本地时间: %s", tm_str);
	 exit(0);
}

在这里插入图片描述
(6)strftime 函数
此函数也可以将一个 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。

测试

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
	 struct tm local_t;
	 char tm_str[100] = {0};
	 time_t sec;
	 /* 获取时间 */
	 sec = time(NULL);
	 if (-1 == sec) {
		 perror("time error");
		 exit(-1);
	 }
	 localtime_r(&sec, &local_t);
	 strftime(tm_str, sizeof(tm_str), "%Y-%m-%d %A %H:%M:%S", &local_t);
	 printf("本地时间: %s\n", tm_str);
	 exit(0);
}

在这里插入图片描述

1.3、设置时间 settimeofday
使用 settimeofday()函数可以设置时间,也就是设置系统的本地时间

#include <sys/time.h>
int settimeofday(const struct timeval *tv, const struct timezone *tz);

三、总结

在这里插入图片描述

四、进程时间

进程时间指的是进程从创建后(也就是程序运行后)到目前为止这段时间内使用 CPU 资源的时间总数,出于记录的目的,内核把 CPU 时间(进程时间)分为以下两个部分:

⚫ 用户 CPU 时间:进程在用户空间(用户态)下运行所花费的 CPU 时间。有时也成为虚拟时间(virtualtime)。
⚫ 系统 CPU 时间:进程在内核空间(内核态)下运行所花费的 CPU 时间。这是内核执行系统调用或代表进程执行的其它任务(譬如,服务页错误)所花费的时间。一般来说,进程时间指的是用户 CPU 时间和系统 CPU 时间的总和,也就是总的 CPU 时间。

Tips:进程时间不等于程序的整个生命周期所消耗的时间,如果进程一直处于休眠状态(进程被挂起、不会得到系统调度),那么它并不会使用 CPU 资源,所以休眠的这段时间并不计算在进程时间中。

1、times 函数

#include <sys/times.h>
clock_t times(struct tms *buf);

函数参数和返回值含义如下:
buf:times()会将当前进程时间信息存在一个 struct tms 结构体数据中。
返回值:返回值类型为 clock_t(实质是 long 类型),调用成功情况下,将返回从过去任意的一个时间点(譬如系统启动时间)所经过的时钟滴答数(其实就是系统节拍数),将(节拍数 / 节拍率)便可得到秒数,返回值可能会超过 clock_t 所能表示的范围(溢出);调用失败返回-1,并设置 errno。

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 时间总和 */
};

测试

#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);
} 

在这里插入图片描述
2、clock 函数
库函数 clock()提供了一个更为简单的方式用于进程时间,它的返回值描述了进程使用的总的 CPU 时间

#include <time.h>
clock_t clock(void);

返回值:返回值是到目前为止程序的进程时间,为 clock_t 类型,注意 clock()的返回值并不是系统节拍数,如果想要获得秒数,请除以 CLOCKS_PER_SEC(这是一个宏)。如果返回的进程时间不可用或其值无法表示,则该返回值是-1。

测试

#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);
}

在这里插入图片描述

五、产生随机数

1、srand 函数

#include <stdlib.h>
void srand(unsigned int seed);

seed:指定一个随机数中,int 类型的数据,一般尝尝将当前时间作为随机数种子赋值给参数 seed,譬如 time(NULL),因为每次启动应用程序时间上是一样的,所以就能够使得程序中设置的随机数种子在每次启动程序时是不一样的。
常用的用法 srand(time(NULL));

测试

#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);
}

在这里插入图片描述

六、休眠

1、秒级休眠: sleep

#include <unistd.h>
unsigned int sleep(unsigned int seconds);

函数参数和返回值含义如下:
seconds:休眠时长,以秒为单位。
返回值:如果休眠时长为参数 seconds 所指定的秒数,则返回 0;若被信号中断则返回剩余的秒数。

2、微秒级休眠: usleep

#include <unistd.h>
int usleep(useconds_t usec);

3、高精度休眠: nanosleep

#include <time.h>
int nanosleep(const struct timespec *req, struct timespec *rem);

函数参数与返回值含义如下:
req:一个 struct timespec 结构体指针,指向一个 struct timespec 变量,用于设置休眠时间长度,可精确到纳秒级别。
rem:也是一个 struct timespec 结构体指针,指向一个 struct timespec 变量,也可设置 NULL。

测试

#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);
} 

在这里插入图片描述

七、申请堆内存

#include <stdlib.h>
void *malloc(size_t size);
#include <stdlib.h>
void free(void *ptr);

测试

#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);
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java拦截器怎么实现

Java拦截器是一种对象拦截器&#xff0c;它可以拦截任何的类、方法和字段。拦截器还可以用于检查类是否已经加载以及对字段的访问权限是否符合规范。下面就让我们来了解一下 java拦截器怎么实现吧。 在 Java中&#xff0c;可以通过重写方法和代码块来实现拦截功能&#xff0c;但…

通俗讲解什么是Socket通讯

Socket通讯原理 1、什么是Socket&#xff1f; Socket&#xff0c;即套接字。就是两台主机之间逻辑连接的端点。&#xff08;通俗来说&#xff1a;网络上的两个程序通过一个双向的通信连接实现数据的交换&#xff0c;这个连接的一端称为一个socket&#xff09;。 Socket是一套…

【python】类和对象 | 一些混淆的知识点再复盘 | 魔术方法(特殊方法)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、魔术方法二、构造方法三、__ getitem __方法四、__ len __方法前言 参考视频&#xff1a;视频 一、魔术方法 首先看一看chatgpt对魔术方法&#xff08;特…

一图看懂 xlsxwriter 模块:用于创建 Excel .xlsx 文件, 资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 xlsxwriter 模块&#xff1a;用于创建 Excel .xlsx 文件, 资料整理笔记&#xff08;大全&#xff09;摘要模块图类关系图模块全展开【xlsxwriter】统计常量模块1 xlsxwrite…

数据爬虫爬数据时常遇到的问题

第一&#xff0c;可能不能直接通过pyppeteer简单的直接page.querySelectorAll()获取所有元素然后直接 str(await (await element_songer_name.getProperty("title")).jsonValue()) 得到数据值&#xff0c;主要原因可能是#document问题&#xff0c; 所以遇到这个问题…

vue项目配置不同环境打包指令(vue-cli2、vue-cli3项目)

目录 一、vue-cli3项目&#xff1a;1、项目根目录创建环境文件2、 配置打包指令3、打包生成不同的dist文件夹 二、vue-cli2项目1、配置指令2.创建环境文件3、config/index.js中添加 三、遇到的问题1.vue-cli3项目配置打包指令&#xff0c;没有生成css文件--mode test2、vue-cli…

UE DTMqtt 虚幻引擎 Mqtt 客户端插件说明

目录 CreateMqttClient Connect Subscribe UnSubscribe Publish Disconnect BindConnectedDelegate BindConnectionLostDelegate BindMessageDelegate CreateMqttClient 创建一个Mqtt客户端对象 Connect 链接Mqtt服务器Subscribe 订阅消息频道UnSubscribe 取消订阅频道…

【go项目-geecache】动手写分布式缓存 - day3 - HTTP 服务端

收获总结&#xff1a; 了解go函数的可变参数的使用&#xff0c;还有切片展开的方式即…了解了HTTP通信方式&#xff0c;hinder的使用了解了go.mod &#xff0c;import 和modoule的使用 分布式缓存需要实现点对点的通信&#xff0c;我们可以使用HTTP来实现节点之间的通信&…

Linux·IO子系统和文件系统读写流程

目录 1.概述 2.linux IO子系统和文件系统读写流程 3.IO之流程与buffer概览 4.IO队列和IO调度 1.概述 分析一下写操作&#xff1a; char *buf malloc(MAX_BUF_SIZE); strncpy(buf, src, , MAX_BUF_SIZE); fwrite(buf, MAX_BUF_SIZE, 1, fp); fclose(fp); 以下图为例&…

九耶丨钛伦特-用深度学习实现垃圾图像分类(二)

3 构建模型 这里大家可以使用自己在项目 2 中寻找到的最好的模型结构&#xff0c;做为示例&#xff0c;这里以实验2-3 中的 snet 模型为基础&#xff0c;并进行细微的调整。 样例代码: 需要注意的是&#xff0c;我们在第一层卷基层之后增加了一层池化层&#xff0c;主要是为了降…

大数据技术之Spark

第1章 Spark概述 1.1 什么是Spark 回顾&#xff1a;Hadoop主要解决&#xff0c;海量数据的存储和海量数据的分析计算。 Spark是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。 Hadoop的Yarn框架比Spark框架诞生的晚&#xff0c;所以Spark自己也设计了一套资源调度…

30天学会《Streamlit》(1)

30学会《Streamlit》是一项编码挑战&#xff0c;旨在帮助您开始构建Streamlit应用程序。特别是&#xff0c;您将能够&#xff1a; 为构建Streamlit应用程序设置编码环境 构建您的第一个Streamlit应用程序 了解用于Streamlit应用程序的所有很棒的输入/输出小部件 第1天 - 建立…

Java面向对象高级【注解和反射】

目录 注解 什么是注解&#xff1f; 自定义注解 元注解 反射 什么是反射 静态语言和动态语言 动态语言 静态语言 对比 Class类 Java内存分析 类加载过程 类加载器 获取运行时类的完整结构 通过Class对象实例化对象 1.调用Class对象的newInstance 2.Constructor…

保姆级教程!如何在 Anolis 8 上构建基于 Nydus 和 Dragonfly 的镜像加速解决方案?

文/云原生 SIG 01 背景 镜像是容器技术的基础之一&#xff0c;在云原生场景下&#xff0c;业务的正常运作离不开对镜像的制作、分发和运行。当前的镜像在使用的过程中&#xff0c;需要将镜像从仓库中全量拉取到本地&#xff0c;再由容器 engine 进行解压&#xff0c;堆叠挂载…

【JUC进阶】详解synchronized锁升级

文章目录 1. synchronized概述2. synchronized 的实现原理2.1 Java对象组成2.2 Monitor2.3 从字节码角度看synchronized 3. 锁升级3.1 偏向锁3.2 轻量级锁 1. synchronized概述 synchronized是一个悲观锁&#xff0c;可以实现线程同步&#xff0c;在多线程的环境下&#xff0c…

信盈达CorexM4核心板STM32F407VGT6电路原理图\电源原理图\USB的工作原理\miniUSB的分类

一、电源部分电路 Micro_USB插座中的5V与GND就是直接提供VCC与GND&#xff0c;其中的D与D-是接在CH340芯片上的实现串口通信的数据口。 电源VCC通过一个自恢复保险丝接在一个自锁开关上,这样就分析完一个miniUSB的提供电源的原理图了。 在原理图的右上角有一个AMS1117-3.3的器件…

RabbitMQ 高级篇 | 黑马

一、消息可靠投递 生产端的 在使用 RabbitMQ的时候&#xff0c;作为消息发送方希望杜绝任何消息丢失或者投递失败场景。 RabbitMQ 为我们提供了两种方式用来控制消息的投递可靠性模式。 confirm 确认模式return 退回模式 rabbitmq整个消息投递的路径为: producer--->ra…

HCIP-6.6BGP配置中IGP路由表和BGP路由表、IP路由表关系

BGP配置中IGP路由表和BGP路由表、IP路由表关系1、基础配置2、配置建立IBGP对等体3、配置EBGP对等体4、使用network命令宣告路由5、路由的学习5.1、R2的路由表5.2、R1的BGP路由表5.3、R3的BGP路由表5.4、R5的BGP路由表6、AS200与AS100通信6.1、AS200出接口注入AS100IP路由表6.2、…

Go 汇编详解

动手点关注干货不迷路前言我们知道 Go 语言的三位领导者中有两位来自 Plan 9 项目&#xff0c;这直接导致了 Go 语言的汇编采用了比较有个性的 Plan 9 风格。不过&#xff0c;我们不能因咽废食而放弃无所不能的汇编。1、 Go 汇编基础知识1.1、通用寄存器不同体系结构的 CPU&…

【Docker】使用Docker Compose部署项目

目录 前言 使用 前言 如果你部署项目需要很多个容器, 并且还是在手动一个一个启动的话来试试Docker Compose, 只需要写好Docker Compose文件运行命令就能帮你一次性全启动, 对微服务很友好啊~ 使用 运行以下命令查看是否有版本号, 确保你已经安装了Docker Compose docker…