3.3 Linux获取系统信息(5、6、7节)

3.3.5.linux中使用随机数

3.3.5.1、随机数和伪随机数

(1)随机数是随机出现,没有任何规律的一组数列。
(2)真正的完全随机的数列是不存在的,只是一种理想情况。我们平时要用到随机数时一般只能通过一些算法得到一个伪随机数序列。
(3)我们平时说到随机数,基本都指的是伪随机数。

3.3.5.2、linux中随机数相关API

(1)连续多次调用rand函数可以返回一个伪随机数序列
(2)srand函数用来设置rand获取的伪随机序列的种子

3.3.5.3、实战演示

(1)单纯使用rand重复调用n次,就会得到一个0-RAND_MAX之间的伪随机数,如果需要调整范围,可以得到随机数序列后再进行计算。
(2)单纯使用rand来得到伪随机数序列有缺陷,每次执行程序得到的伪随机序列是同一个序列,没法得到其他序列
(3)原因是因为rand内部的算法其实是通过一个种子(seed,其实就是一个原始参数,int类型),rand内部默认是使用1作为seed的,种子一定的算法也是一定的,那么每次得到的伪随机序列肯定是同一个。

(4)所以要想每次执行这个程序获取的伪随机序列不同,则每次都要给不同的种子。用srand函数来设置种子。

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



int main(int argc, char **argv)
{
	int i = 0, val = 0;
	
/*	if (argc != 2)
	{
		printf("usage: %s num\n", argv[0]);
		return -1;
	}
*/	
	printf("RAND_MAX = %d.\n", RAND_MAX);		// 2147483647
	
	//srand(atoi(argv[1]));
	srand(time(NULL));
	for (i=0; i<6; i++)
	{
		val = rand();
		printf("%d ", (val % 6));
	}
	printf("\n");
	
	return 0;
}

3.3.5.4、总结和说明

(1)在每次执行程序时,先用srand设置一个不同的种子,然后再多次调用rand获取一个伪随机序列,这样就可以每次都得到一个不同的伪随机序列。
(2)一般常规做法是用time函数的返回值来做srand的参数。

3.3.5.5、在linux系统中获取真正的随机数

(1)linux系统收集系统中的一些随机发生的事件的时间(譬如有人动鼠标,譬如触摸屏的操作和坐标等)作为随机种子去生成随机数序列。


3.3.6.proc文件系统介绍

3.3.6.1、操作系统级别的调试

(1)简单程序单步调试
(2)复杂程序printf打印信息调试
(3)框架体系日志记录信息调试
(4)内核调试的困境

3.3.6.2、proc虚拟文件系统的工作原理

(1)linux内核是一个非常庞大、非常复杂的一个单独的程序,对于这样的一个程序来说调试是非常复杂的。
(2)项kernel这样庞大的项目,给里面添加/更改一个功能是非常麻烦的,因为你这添加的一个功能可能会影响其他已经有的。
(3)早期内核版本中尽管调试很麻烦,但是高手们还可以凭借个人超凡脱俗的能力去驾驭。但是到了2.4左右的版本的时候,这个难度已经非常大了。
(4)为了降低内核调试和学习的难度,内核开发者们在内核中添加了一些属性专门用于调试内核,proc文件系统就是一个尝试。
(5)proc文件系统的思路是:在内核中构建一个虚拟文件系统/proc,内核运行时将内核中一些关键的数据结构以文件的方式呈现在/proc目录中的一些特定文件中,这样相当于将不可见的内核中的数据结构以可视化的方式呈现给内核的开发者。
(6)proc文件系统给了开发者一种调试内核的方法:我们通过实时的观察/proc/xxx文件,来观看内核中特定数据结构的值。在我们添加一个新功能的前后来对比,就可以知道这个新功能产生的影响对还是不对。
(7)proc目录下的文件大小都是0,因为这些文件本身并不存在于硬盘中,他也不是一个真实文件,他只是一个接口,当我们去读取这个文件时,其实内核并不是去硬盘上找这个文件,而是映射为内核内部一个数据结构被读取并且格式化成字符串返回给我们。所以尽管我们看到的还是一个文件内容字符串,和普通文件一样的;但是实际上我们知道这个内容是实时的从内核中数据结构来的,而不是硬盘中来的。

3.3.6.3、常用proc中的文件介绍

(1)/proc/cmdline
(2)/proc/cpuinfo
(3)/proc/devices

(4)/proc/interrupts


3.3.7.proc文件系统的使用

3.3.7.1、cat以手工查看

3.3.7.2、程序中可以文件IO访问

3.3.7.3、在shell程序中用cat命令结合正则表达式来获取并处理内核信息

3.3.7.3、扩展:sys文件系统

(1)sys文件系统本质上和proc文件系统是一样的,都是虚拟文件系统,都在根目录下有个目录(一个是/proc目录,另一个是/sys目录),因此都不是硬盘中的文件,都是内核中的数据结构的可视化接口。
(2)不同的是/proc中的文件只能读,但是/sys中的文件可以读写。读/sys中的文件就是获取内核中数据结构的值,而写入/sys中的文件就是设置内核中的数据结构的元素的值。
(3)历史上刚开始先有/proc文件系统,人们希望通过这种技术来调试内核。实际做出来后确实很有用,所以很多内核开发者都去内核调价代码向/proc目录中写文件,而且刚开始的时候内核管理者对proc目录的使用也没有什么经验也没什么统一规划,后来的结果就是proc里面的东西又多又杂乱。

(4)后来觉得proc中的内容太多太乱缺乏统一规划,于是乎又添加了sys目录。sys文件系统一开始就做了很好的规划和约定,所以后来使用sys目录时有了规矩。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


int main(int argc, char **argv)
{
	int fd = -1;
	char buf[512] = {0};
	
	if (argc != 2)
	{
		printf("usage: %s -v|-d\n", argv[0]);
		return -1;
	}
	
	if (!strcmp(argv[1], "-v"))
	{
		fd = open("/proc/version", O_RDONLY);
		if (fd < 0)
		{
			perror("open /proc/version");
			return -1;
		}
		read(fd, buf, sizeof(buf));
		printf("结果是:%s.\n", buf);
	}
	else if (!strcmp(argv[1], "-d"))
	{
		fd = open("/proc/devices", O_RDONLY);
		if (fd < 0)
		{
			perror("open /proc/devices");
			return -1;
		}
		read(fd, buf, sizeof(buf));
		printf("结果是:%s.\n", buf);
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_33662195/article/details/73246911
3.3