Linux获取系统信息

1.Linux中的时间

1.1GMT时间和UTC时间、定时器和实时时钟

GMT时间和UTC时间:

  • GMT时间是指位于伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。用格林尼治的当地时间作为全球国际时间,用以描述全球性的事件的时间。
  • GMT时间是以前使用的,近些年来越来越多的使用UTC时间。协调世界时(UTC) 是世界统一时间,世界标准时间国际协调时间, 协调世界时,又称世界统一时间,世界标准时间,
  • UTC+(+0800)=北京时间

定时器和实时时钟:

  • 定时器(timer)定的时间就是段时间。
  • 实时时钟(RTC)和点时间有关。

1.2 jiffies详解

  • jiffies是linux内核中的一个全局变量,这个变量用来记录以内核的节拍时间为单位时间长度的一个数值。内核配置的时候定义了一个节拍时间,实际上linux内核的调度系统工作时就是以这个节拍时间为时间片的。jiffies变量开机时有一个基准值,内核每过一个节拍时间jiffies就会加1,然后到了系统的任意一个时间我们当前时间就被jiffies这个变量所标注。
  • 内核在开机启动的时候会读取RTC硬件获取一个初始基准时间,这个基准时间对应一个jiffies值(基准时间换算成jiffies值的方法是:用这个时间减去1970-01-01 00:00:00 +0000(UTC),然后把这个时间段换算成jiffies数值),这个jiffies值作为开机时的基准jiffies值存在。然后系统运行时每个时钟节拍的末尾都会给jiffies这个全局变量加1,操作系统就使用jiffies这个全局变量记录了下来当前的时间。当我们需要当前时间点时,就用jiffies这个时间点去计算(计算方法就是先把这个jiffies值对应的时间段算出来,然后加上1970-01-01 00:00:00 +0000(UTC))。
  • 操作系统只在开机时读一次RTC,整个系统运行过程中RTC是无作用的。RTC的真正作用其实是在系统的2次开机之间进行时间的保存。jiffies这个变量记录的其实是段时间(其实就是当前时间和1970-01-01 00:00:00 +0000(UTC)这个时间的差值)。
  • 一个节拍的时间取决于操作系统的配置,现代Linux系统一般是10ms或者1ms。这个时间其实就是调度时间,在内核中用HZ来记录和表示。如果HZ定义成1000难么时钟节拍就是1/HZ,也就是1ms。

1.3Linux中和时间相关的API

time:

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

time系统调用返回当前时间以秒为单位的距离1970-01-01 00:00:00 +0000(UTC)过去的秒数。这个time内部就是用jiffies换算得到的秒数。其他函数基本都是围绕着time来工作的。


ctime:

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

ctime是C库函数,它可以从time_t出发得到一个容易观察的字符串格式的当前时间。


gmtimelocaltimemktime:

#include <time.h>
struct tm *gmtime(const time_t *timep);
struct tm *localtime(const time_t *timep);
time_t mktime(struct tm *tm);

struct tm:

struct tm {
	int tm_sec;    /* Seconds (0-60) */
	int tm_min;    /* Minutes (0-59) */
	int tm_hour;   /* Hours (0-23) */
	int tm_mday;   /* Day of the month (1-31) */
	int tm_mon;    /* Month (0-11) */
	int tm_year;   /* Year - 1900 */
	int tm_wday;   /* Day of the week (0-6, Sunday = 0) */
	int tm_yday;   /* Day in the year (0-365, 1 Jan = 0) */
	int tm_isdst;  /* Daylight saving time */
};

gmtime和localtime会把time得到的秒数变成一个struct tm结构体表示的时间。区别是gmtime得到的是国际时间,而localtime得到的本地时间。mktime用来完成相反方向的转换(struct tm–>time_t)。


asctimestrftime:

 #include <time.h>
char *asctime(const struct tm *tm);
size_t strftime(char *s, size_t max, const char *format,const struct tm *tm);

如果从struct tm出发想得到字符串格式的时间,asctime或者strftime都可以。


gettimeofdaysettimeofday

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

struct timevalstruct timezone

struct timeval {
	time_t      tv_sec;     /* seconds */
	suseconds_t tv_usec;    /* microseconds */
};
struct timezone {
	int tz_minuteswest;     /* minutes west of Greenwich */
	int tz_dsttime;         /* type of DST correction */
};

gettimeofday返回的时间是由struct timeval和struct timezone这两个结构体来共同表示的,其中timeval表示时间,而timezone表示时区。settimeofday是用来设置当前的时间和时区的。


  • 总结:不管用哪个系统调用,最终得到的时间本质上都是一个时间(这个时间最终都是从kernel中记录的jiffies中计算得来的),只不过不同的函数返回的时间的格式不同,精度不同。

3.3.3.3、gmtime和localtime
(1)gmtime获取的时间中:年份是以1970为基准的差值,月份是0表示1月,小时数是以UTC时间的0时区为标准的小时数(北京是东8区,因此北京时间比这个时间大8)
(2)猜测localtime和gmtime的唯一区别就是localtime以当前计算机中设置的时区为小时的时间基准,其余一样。实践证明我们的猜测是正确的。

2.获取随机数

随机数是随机出现,没有任何规律的一组数列。真正的完全随机的数列是不存在的,只是一种理想情况,一般只能通过一些算法得到一个伪随机数序列。
rand()函数和srand()函数:

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

单纯使用rand每次执行程序得到的伪随机序列是同一个序列,没法得到其他序列,因为rand内部的算法是通过一个种子(seed,一个int类型的原始参数,默认为1),作为seed的,种子一定则算法也是一定的,所以每次得到的伪随机序列是同一个。
因此要想每次执行这个程序获取的伪随机序列不同,则每次都要给不同的种子。srand函数就是用来设置随机种子的。

随机数示例(获取长度为10,大小为0-5之间的随机序列):

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

int main(int argc, char **argv)
{
	int val = 0;
	srand(time(NULL));
	for (int i=0; i<10; i++)
	{
		val = rand();
		printf("%d ", (val % 6));
	}
	printf("\n");
	
	return 0;
}

output:

5 2 1 3 0 5 2 1 2 4 
  • 总结:在每次执行程序时,先用srand设置一个不同的种子,然后再多次调用rand获取一个伪随机序列,这样就可以每次都得到一个不同的伪随机序列(一般做法是用time函数的返回值来做srand的参数)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值