Linux系统相关函数总结

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

系统信息

系统标识 uname

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

时间和日期

Ubuntu 系统下,可以使用 date 命令查看系统当前的本地时间,如下所示:

可以看到显示出来的字符串后面有一个"CST"字样,CST 在这里其实指的是 China Standard Time(中国 标准时间)的缩写,表示当前查看到的时间是中国标准时间,也就是我国所使用的标准时间--北京时间,一般在安装 Ubuntu 系统的时候会提示用户设置所在城市,那么系统便会根据你所设置的城市来确定系统的本地时间对应的时区,譬如设置的城市为上海,那么系统的本地时间就是北京时间,因为我国统一使用北京时间作为本国的标准时间。

Ubuntu 系统下,时区信息通常以标准格式保存在一些文件当中,这些文件通常位于/usr/share/zoneinfo目录下,该目录下的每一个文件(包括子目录下的文件)都包含了一个特定国家或地区内时区制度的相关信息,且往往根据其所描述的城市或地区缩写来加以命名,譬如 EST(美国东部标准时间)、CET(欧洲中部时间)、UTC(世界标准时间)、HongkongIranJapan(日本标准时间)等,也把这些文件称为时区配置文件,如下图所示:

Linux系统如何记录时间

操作系统中一般会有两个时钟,一个系统时钟(system clock),一个实时时钟(Real time clock),也 叫 RTC;系统时钟由系统启动之后由内核来维护,譬如使用 date 命令查看到的就是系统时钟,所以在系统关机情况下是不存在的;而实时时钟一般由 RTC 时钟芯片提供,RTC 芯片有相应的电池为其供电,以保证系统在关机情况下 RTC 能够继续工作、继续计时。

Linux 系统如何记录时间?

Linux 系统在开机启动之后首先会读取 RTC 硬件获取实时时钟作为系统时钟的初始值,之后内核便开始维护自己的系统时钟。所以由此可知,RTC 硬件只有在系统开机启动时会读取一次,目的是用于对系统时钟进行初始化操作,之后的运行过程中便不会再对其进行读取操作了。而在系统关机时,内核会将系统时钟写入到 RTC 硬件,以进行同步操作。

jiffies的引入

jiffies 是内核中定义的一个全局变量,内核使用 jiffies 来记录系统从启动以来的系统节拍数,所以这个变量用来记录以系统节拍时间为单位的时间长度,Linux 内核在编译配置时定义了一个节拍时间,使用节拍率(一秒钟多少个节拍数)来表示,譬如常用的节拍率为 100Hz(一秒钟 100 个节拍数,节拍时间为 1s /100)、200Hz(一秒钟 200 个节拍,节拍时间为 1s / 200)、250Hz(一秒钟 250 个节拍,节拍时间为 1s /250)、300Hz(一秒钟 300 个节拍,节拍时间为 1s / 300)、500Hz(一秒钟 500 个节拍,节拍时间为 1s /500)等。由此可以发现配置的节拍率越高,每一个系统节拍的时间就越短,也就意味着 jiffies 记录的时间精度越高,当然,高节拍率会导致系统中断的产生更加频繁,频繁的中断会加剧系统的负担,一般默认情况下都是采用 100Hz 作为系统节拍率。

这里其实也是linux系统的任务调度频率,也就是说,linux的任务调度,每10ms切换一次。而在RTOS中,一般都是1ms。这也是为什么Linux不是实时操作系统的原因之一。

内核其实通过 jiffies 来维护系统时钟,全局变量 jiffies 在系统开机启动时会设置一个初始值,上面也给大家提到过,RTC 实时时钟会在系统开机启动时读取一次,目的是用于对系统时钟进行初始化,这里说的初始化其实指的就是对内核的 jiffies 变量进行初始化操作,具体如何将读取到的实时时钟换算成 jiffies 数值,这里便不再给大家介绍了。
所以由此可知,操作系统使用 jiffies 这个全局变量来记录当前时间,当我们需要获取到系统当前时间点时,就可以使用 jiffies 变量去计算,当然并不需要我们手动去计算,Linux 系统提供了相应的系统调用或 C库函数用于获取当前时间,譬如系统调用 time()、gettimeofday(),其实质上就是通过 jiffies 变量换算得到。

由此也可知,通过这种方式得到的时间,精度只有10ms(100Hz系统频率的前提下)

获取日历时间

time函数
系统调用 time()用于获取当前时间,以秒为单位,返回得到的值是自 1970-01-01 00:00:00 +0000 (UTC)以来的秒数。我们把这个称之为日历时间或 time_t 时间。

gettimeofday函数
time()获取到的时间只能精确到秒,如果想要获取更加精确的时间可以使用系统调用gettimeofday 来实现,gettimeofday()函数提供微秒级时间精度,函数原型如下所示(可通过"man 2 gettimeofday"命令查看):

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

使用该函数需要包含头文件<sys/time.h>。 

参数 tv 是一个 struct timeval 结构体指针变量;

struct timeval {long tv_sec; /* 秒 */ long tv_usec; /* 微秒 */
};

获取得到的时间值存储在参数 tv 所指向的 struct timeval 结构体变量中,该结构体包含了两个成员变量tv_sec 和 tv_usec,分别用于表示秒和微秒,所以获取得到的时间值就是 tv_sec(秒)和tv_usec(微秒),其中,tv_sec的值和 time()函数获取到的一样。
tz:参数 tz 是个历史产物,早期实现用其来获取系统的时区信息,目前已遭废弃,在调用gettimeofday()函数时应将参数 tz 设置为 NULL。

返回值:成功返回 0;失败将返回-1,并设置 errno。

示例如下:

注意,这个秒和毫秒不是等价的关系,而是叠加的关系。

只是time函数省略掉了秒以下的时间精度。

时间转换 

通过 time()或 gettimeofday()函数可以获取到当前时间点相对于 1970-01-01 00:00:00 +0000 (UTC)这个时间点所经过时间(日历时间),所以获取得到的是一个时间段的长度,但是这并不利于我们查看当前时间,这个结果对于我们来说非常不友好,那么接下来将学习一些系统调用或 C 库函数,通过这些 API 可以将 time()或 gettimeofday()函数获取到的秒数转换为利于查看和理解的形式。 

ctime函数
ctime()是一个 C 库函数,可以将日历时间转换为可打印输出的字符串形式,ctime()函数原型如下所示:

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

使用该函数需要包含头文件<time.h>。
函数参数和返回值含义如下:
timep:time_t 时间变量指针。
返回值:成功将返回一个 char *类型指针,指向转换后得到的字符串;失败将返回 NULL。

所以由此可知,使用 ctime 函数非常简单,只需将 time_t 时间变量的指针传入即可,调用成功便可返回字符串指针,拿到字符串指针之后,可以使用 printf 将其打印输出。但是 ctime()是一个不可重入函数,存在一些安全上面的隐患,ctime_r()是 ctime()的可重入版本,一般推荐大家使用可重入函数 ctime_r(),可重入函数 ctime_r()多了一个参数 buf,也就是缓冲区首地址,所以 ctime_r()函数需要调用者提供用于存放字符串的缓冲区。ctime(或ctime_r)转换得到的时间是计算机所在地对应的本地时间(譬如在中国对应的便是北京时间),并不是 UTC 时间。

示例如下:

结果如下:

不过,这种形式的可读性也一般。

localtime函数
localtime()函数可以把 time()或 gettimeofday()得到的秒数(time_t 时间或日历时间)变成一个 struct tm结构体所表示的时间,该时间对应的是本地时间。localtime 函数原型如下:

#include <time.h>
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);

使用该函数需要包含头文件<time.h>,localtime()的可重入版本为 localtime_r()。

函数参数和返回值含义如下:

timep:需要进行转换的 time_t 时间变量对应的指针,可通过 time()或 gettimeofday()获取得到。

result:是一个 struct tm 结构体类型指针,稍后给大家介绍 struct tm 结构体,参数 result 是可重入函数localtime_r()需要额外提供的参数。

返回值:对于不可重入版本 localtime()来说,成功则返回一个有效的 struct tm 结构体指针,而对于可重入版本 localtime_r()来说,成功执行情况下,返回值将会等于参数 result;失败则返回 NULL。使用不可重入函数 localtime()并不需要调用者提供 struct tm 变量,而是它会直接返回出来一个 struct tm结构体指针,然后直接通过该指针访问里边的成员变量即可!虽然很方便,但是存在一些安全隐患,所以一般不推荐使用不可重入版本。使用可重入版本 localtime_r()调用者需要自己定义 struct tm 结构体变量、并将该变量指针赋值给参数result,在函数内部会对该结构体变量进行赋值操作。 

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;/* 夏令时 */
};
从 struct tm 结构体内容可知,该结构体中包含了年月日时分秒星期等信息,使用localtime/localtime_r()便可以将 time_t 时间总秒数分解成了各个独立的时间信息,易于我们查看和理解。
示例如下:

gmtime函数

gmtime()函数也可以把 time_t 时间变成一个 struct tm 结构体所表示的时间,与 localtime()所不同的是,gmtime()函数所得到的是 UTC 国际标准时间,并不是计算机的本地时间,这是它们之间的唯一区别。 

strftime函数
再给大家介绍一个 C 库函数 strftime(),此函数可以将一个 struct tm 变量表示的分解时间转换为为格式化字符串,并且可以根据自己的喜好自定义时间的显示格式。

具体参考:C 库函数 – strftime() | 菜鸟教程 (runoob.com)

其实就是通过特定的符号来取struct tm中的对应数据,然后生成一个字符串而已。

进程时间

进程时间指的是进程从创建后(也就是程序运行后)到目前为止这段时间内使用 CPU 资源的时间总数,
出于记录的目的,内核把 CPU 时间(进程时间)分为以下两个部分:
⚫ 用户 CPU 时间:进程在用户空间(用户态)下运行所花费的 CPU 时间。有时也成为虚拟时间(virtualtime)。
⚫ 系统 CPU 时间:进程在内核空间(内核态)下运行所花费的 CPU 时间。这是内核执行系统调用或代表进程执行的其它任务(譬如,服务页错误)所花费的时间。
一般来说,进程时间指的是用户 CPU 时间和系统 CPU 时间的总和,也就是总的 CPU 时间。
Tips:进程时间不等于程序的整个生命周期所消耗的时间,如果进程一直处于休眠状态(进程被挂起、不会得到系统调度),那么它并不会使用 CPU 资源,所以休眠的这段时间并不计算在进程时间中。

times函数(注意和time函数区分开)
times()函数用于获取当前进程时间,其函数原型如下所示:

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

使用该函数需要包含头文件<sys/times.h>。

函数参数和返回值含义如下:

buf:times()会将当前进程时间信息存在一个 struct tms 结构体数据中,所以我们需要提供 struct tms 变量,使用参数 buf 指向该变量。

更多略。。。。。。

随机数

具体参考:

C 库函数 – rand() | 菜鸟教程 (runoob.com)

使用 rand()srand()产生一组伪随机数

 

休眠

秒级休眠: sleep

微秒级休眠: usleep

高精度休眠: nanosleep

注意,没有毫秒级休眠。。。。。。

在应用程序当中,通常使用这些函数作为延时功能,譬如在程序当中需要延时一秒钟、延时
5 毫秒等应用场景时,那么就可以使用这些函数来实现;但是大家需要注意,休眠状态下,该进程会失去 CPU使用权,退出系统调度队列,直到休眠结束。在一个裸机程序当中,通常使用 for 循环(或双重 for 循环)语句来实现延时等待,譬如在 for 循环当中执行 nop 空指令,也就意味着即使在延时等待情况下,CPU 也是一直都在工作;由此可知,应用程序当中使用休眠用作延时功能,并不是裸机程序中的 nop 空指令延时,一旦执行 sleep(),进程便主动交出 CPU 使用权,暂时退出系统调度队列,在休眠结束前,该进程的指令将得不到执行。 

申请堆内存

在堆上分配内存:malloc 和 free
Linux C 程序当中一般使用 malloc()函数为程序分配一段堆内存,而使用 free()函数来释放这段内存。

C 函数库中还提供了一系列在堆上分配对齐内存的函数,对齐内存在某些应用场合非常有必要,常用于分配对其内存的库函数有:posix_memalign()、aligned_alloc()、memalign()、valloc()、pvalloc(),具体需要时查阅即可。

proc文件系统

proc 文件系统是一个虚拟文件系统,它以文件系统的方式为应用层访问系统内核数据提供了接口,用户和应用程序可以通过 proc 文件系统得到系统信息和进程相关信息,对 proc 文件系统的读写作为与内核进行通信的一种手段。但是与普通文件不同的是,proc 文件系统是动态创建的,文件本身并不存在于磁盘当中、只存在于内存当中,与 devfs 一样,都被称为虚拟文件系统。
最初构建 proc 文件系统是为了提供有关系统中进程相关的信息,但是由于这个文件系统非常有用,因此内核中的很多信息也开始使用它来报告,或启用动态运行时配置。内核构建 proc 虚拟文件系统,它会将内核运行时的一些关键数据信息以文件的方式呈现在 proc 文件系统下的一些特定文件中,这样相当于将一些不可见的内核中的数据结构以可视化的方式呈现给应用层。
proc 文件系统挂载在系统的/proc 目录下,对于内核开发者(譬如驱动开发工程师)来说,proc 文件系统给了开发者一种调试内核的方法:通过查看/proc/xxx 文件来获取到内核特定数据结构的值,在添加了新功能前后进行对比,就可以判断此功能所产生的影响是否合理。/proc 目录下中包含了一些目录和虚拟文件,如下所示: 

可以看到 /proc 目录下有很多以数字命名的文件夹,譬如 100038 2299 98560 ,这些数字对应的其实就是一个一个的进程 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 文件系统的使用
proc 文件系统的使用就是去读取/proc 目录下的这些文件,获取文件中记录的信息,可以直接使用 cat 命令读取,也可以在应用程序中调用 open()打开、然后再使用 read()函数读取。
使用 cat 命令读取
在 Linux 系统下直接使用 cat 命令查看/proc 目录下的虚拟文件,譬如"cat /proc/version"查看内核版本相关信息:
使用 read() 函数读取
编写一个简单地程序,使用 read() 函数读取 /proc/version 文件。
更多待补充。

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

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

相关文章

Day.js

Day.js 是什么&#xff1f; Day.js是一个极简的JavaScript库&#xff0c;可以为现代浏览器解析、验证、操作和显示日期和时间。 Day.js中文网 为什么要使用Day.js &#xff1f; 因为Day.js文件只有2KB左右&#xff0c;下载、解析和执行的JavaScript更少&#xff0c;为代码留下更…

高考志愿不知道怎么填?教你1招,用这款AI工具,立省4位数

高中的岁月&#xff0c;就像一本厚厚的书&#xff0c;我们一页页翻过&#xff0c;现在&#xff0c;终于翻到了最后一页。但这不是结束&#xff0c;这是新的开始&#xff0c;是人生的新篇章。 高考落幕&#xff0c;学子们在短暂的放松后&#xff0c;又迎来了紧张的志愿填报。 “…

【机器学习300问】134、什么是主成分分析(PCA)?

假设你的房间堆满了各种各样的物品&#xff0c;书籍、衣服、玩具等等&#xff0c;它们杂乱无章地散落各处。现在&#xff0c;你想要清理房间&#xff0c;但又不想扔掉任何东西&#xff0c;只是希望让房间看起来更整洁&#xff0c;更容易管理。 你开始思考&#xff0c;能否将物品…

苹果笔记本双系统怎么安装

想要在mac电脑上装双系统&#xff0c;首先需要确认您的电脑是否支持。苹果电脑自带的boot camp工具可以帮助您在mac上安装windows系统&#xff0c;只需按照步骤进行操作即可。另外&#xff0c;您也可以使用虚拟机软件&#xff0c;如parallels desktop或vmware fusion&#xff0…

地铁中的CAN通信--地铁高效安全运转原理

目前地铁采用了自动化的技术来实现控制,有ATC(列车自动控制)系统可以实现列车自动驾驶、自动跟踪、自动调度;SCADA(供电系统管理自动化)系统可以实现主变电所、牵引变电所、降压变电所设备系统的遥控、遥信、遥测;BAS(环境监控系统)和FAS(火灾报警系统)可以实现车站…

mmdetection2.28修改backbone不使用预训练参数、从头训练

背景 最近需要测试一下在backbone部分如果不使用预训练参数的话&#xff0c;模型需要多少轮才能收敛所使用的backbone是mmcls.ConvNeXtmmdetection版本为2.28.2&#xff0c;mmcls版本为0.25.0 修改流程 最简单的方法&#xff0c;直接去mmcls的model zoo里找到对应backbone的…

NAND闪存巨头铠侠(Kioxia)计划最迟于10月下旬通过首次公开募股IPO

据路透社于6月26日引用消息来源的报道&#xff0c;在半导体市场条件反弹及财务业绩迅速改善的背景下&#xff0c;NAND闪存巨头铠侠&#xff08;Kioxia&#xff09;正准备尽快提交初步申请&#xff0c;并计划最迟于10月下旬通过首次公开募股&#xff08;IPO&#xff09;在东京证…

可转债交易的规则,权限开通条件。可转债的佣金最低标准万0.44!

可转债交易规则 【1】可转债最小交易单位为1手&#xff0c;1手10张&#xff0c;每张的价格就是大家看到的价格。这和股票很不一样&#xff0c;股票的1手是100股股票。可转债最小价格变动单位为0.001 【2】可转债是T0交易&#xff0c;即当天买入&#xff0c;当天就可以卖出。这…

全新版的 FinClip 也太好用了吧

自 2017 年 FinClip 小程序管理平台发布直至 2023 年已经走过了 6 年。在这一路中我们惊喜的看到 FinClip 在各行业的客户支持下开枝散叶&#xff0c;逐渐承载了不同行业客户对于「数字场景拓展与增长」的期待。 在早期版本的 FinClip 设计中&#xff0c;我们对产品的边界认识…

62.指针和二维数组(2)

一.指针和二维数组 1.如a是一个二维数组&#xff0c;则数组中的第i行可以看作是一个一维数组&#xff0c;这个一维数组的数组名是a[i]。 2.a[i]代表二维数组中第i行的首个元素的地址&#xff0c;即a[i][0]的地址。 二.进一步思考 二维数组可以看作是数组的数组&#xff0c;本…

线性相关,无关?秩?唯一解(只有零解),无穷解(有非零解)?D=0,D≠0?

目录 线性有关无关 和 唯一解&#xff08;只有零解&#xff09;&#xff0c;无穷解&#xff08;有非零解&#xff09;之间的关系 D0&#xff0c;D≠0&#xff1f; 和 秩 的关系 串起来&#xff1a; 线性相关&#xff0c;无关&#xff1f;秩&#xff1f;唯一解&#xff08;只…

golang 实现继承方式

经常使用java或c同学应该比较了解纯面向对象&#xff0c;继承、接口、封装等特性&#xff0c;在go中并没有特别显示的表达出来&#xff0c;但是go隐含是支持的&#xff0c;只是支持的方式不一致&#xff0c;可以说go的方式更加灵活&#xff0c;go语言精髓是组合机制&#xff0c…

VMware 最新的安全漏洞公告VMSA-2024-0013

#深度好文计划# 一、摘要 2024年6月26日&#xff0c;VMware 发布了最新的安全漏洞公告 VMSA-2024-0013&#xff0c;修复了 VMware ESXi 和 VMware vCenter 中的多个安全漏洞。 VMSA-2024-0013&#xff1a;VMware ESXi 和 vCenter Server 更新修正了多个安全性漏洞 &#xff…

2024/5/9【贪心5/5】--代码随想录算法训练营day36|56. 合并区间、738.单调递增的数字、968.监控二叉树 (可跳过)

56. 合并区间 力扣链接 class Solution:def merge(self, intervals):result []if len(intervals) 0:return result # 区间集合为空直接返回intervals.sort(keylambda x: x[0]) # 按照区间的左边界进行排序result.append(intervals[0]) # 第一个区间可以直接放入结果集中…

JavaSE 利用正则表达式进行本地和网络爬取数据(爬虫)

爬虫 正则表达式的作用 作用1&#xff1a;校验字符串是满足规则 作用2&#xff1a;在一段文本中查找满足需要的内容 本地爬虫和网络爬虫 Pattern类 表示正则表达式 Matter类 文本编译器&#xff0c;作用按照正则表达式的规则去读取字符串&#xff0c;从头开始读取&#xf…

C++ 入门

前言 c的发展史&#xff1a; C的起源可以追溯到1979年&#xff0c;当时Bjarne Stroustrup在贝尔实验室开始开发一种名为“C with Classes”的语言。以下是C发展的几个关键阶段&#xff1a; 1979年&#xff1a;Bjarne Stroustrup在贝尔实验室开始开发“C with Classes”。1983…

ONLYOFFICE 桌面编辑器 8.1华丽登场

简介&#xff1a;全新ONLYOFFICE 桌面编辑器 8.1解锁全新PDF编辑、幻灯片优化与本地化体验&#xff0c;立即下载&#xff01; 前言&#xff1a;在数字化时代&#xff0c;高效的办公协作工具是企业和个人不可或缺的利器。ONLYOFFICE&#xff0c;作为一款功能强大的云端和桌面办公…

CSS的媒体查询:响应式布局的利器

关于CSS的媒体查询 CSS媒体查询是CSS层叠样式表(Cascading Style Sheets)中的一个核心功能&#xff0c;它使得开发者能够根据不同的设备特性和环境条件来应用不同的样式规则。这是实现响应式网页设计的关键技术&#xff0c;确保网站或应用能够在多种设备上&#xff0c;包括桌面…

python FastAPI操作数据库实现注册登录

代码如下 from fastapi import FastAPI, APIRouter, HTTPException, status from pydantic import BaseModel from fastapi.responses import JSONResponse from typing import Optional from fastapi.middleware.cors import CORSMiddleware from utils.time import DateTime…

React的Props、生命周期

Props 的只读性 “Props” 是 React 中用于传递数据给组件的一种机制&#xff0c;通常作为组件的参数进行传递。在 React 中&#xff0c;props 是只读的&#xff0c;意味着一旦将数据传递给组件的 props&#xff0c;组件就不能直接修改这些 props 的值。所以组件无论是使用函数…