zoukankan      html  css  js  c++  java
  • 编程获取linuxservercpu、内存和磁盘使用

    proc文件系统简介

    /proc文件系统是一个伪文件系统。它是唯一的,其中存储器,如果不采取外部存储空间。

    它是文件系统提供了与内核进程进行通信的接口的方法。用程序能够通过/proc得到系统的信息。并能够改变内核的某些參数。

    因为系统的信息。如进程。是动态改变的,所以用户或应用程序读取/proc文件夹中的文件时。proc文件系统是动态从系统内核读出所需信息并提交的。


    /proc文件夹中有一些以数字命名的文件夹。它们是进程文件夹。系统中当前执行的每个进程在/proc下都相应一个以进程号为文件夹名的文件夹/proc/pid,它们是读取进程信息的接口。

    此外,在Linux 2.6.0-test6以上的版本号中/proc/pid文件夹中有一个task文件夹,/proc/pid/task文件夹中也有一些以该进程所拥有的线程的线程号命名的文件夹/proc/pid/task/tid,它们是读取线程信息的接口。


    CPU使用率

    要想计算CPU使用率,首先要了解文件/proc/stat中的内容,例如以下是本人所使用server中该文件里的内容:


    CPU 以及CPU0、CPU1、CPU2、CPU3、CPU4中每行的每一个參数意思(以第一行为例)解释:
    user (28201) :从系统启动開始累计到当前时刻。用户态的CPU时间(单位:jiffies) ,不包括 nice值为负进程。1jiffies=0.01秒
    nice (389) :从系统启动開始累计到当前时刻,nice值为负的进程所占用的CPU时间(单位:jiffies)
    system (10975) :从系统启动開始累计到当前时刻,核心时间(单位:jiffies)
    idle (6552431) :从系统启动開始累计到当前时刻,除硬盘IO等待时间以外其他等待时间(单位:jiffies)
    iowait (19704) :从系统启动開始累计到当前时刻,硬盘IO等待时间(单位:jiffies) 。
    irq (0) :从系统启动開始累计到当前时刻。硬中断时间(单位:jiffies)
    softirq (208): 从系统启动開始累计到当前时刻。软中断时间(单位:jiffies)

    获取cpu使用率的方法:

    1、记录某个时刻cpu的使用情况

    2、等上一个时间段

    3、再记录此刻的cpu使用情况

    4、计算总的时间片

    把第一次的全部cpu使用情况求和。得到j1,把第二次的全部cpu使用情况求和,得到j2。则j2-j1得到这个时间段的全部时间片。即total=j2-j1=第二次的全部列的和-第一次的全部列的和

    5、计算idle时间

    idle相应第五列的数据,用第二次的减去第一次的就可以。idle=第二次的第五列-第一次的第五列

    6、计算cpu使用率

    ate=(total-idle)/total

    在代码里实现例如以下所看到的:

    SysCPUInfo* 
    _GetHostCPUInfo()
    {
    	SysCPUInfo *cpuinfo = (SysCPUInfo *)malloc(sizeof(SysCPUInfo));
    	if (cpuinfo == NULL)
    	  err_dump("_GetCPUInfo: malloc struct SysCPUInfo error");
    
    	FILE 	*fd;
    	char	buff[256];
    	memset(buff, '', 256);
    
    	fd = fopen("/proc/stat", "r");
    	fgets(buff, sizeof(buff), fd);
    
    	sscanf(buff, "%s %lu %lu %lu %lu", cpuinfo->name, &cpuinfo->user, &cpuinfo->nic, 
    				&cpuinfo->system, &cpuinfo->idle);
    	fclose(fd);
    	return cpuinfo;
    }
    
    float
    _CalculateHostCPURate(SysCPUInfo *first, SysCPUInfo *second)
    {
    	unsigned long	old_CPU_Time, new_CPU_Time;
    	unsigned long	usr_Time_Diff, sys_Time_Diff, nic_Time_Diff;
    	float 			cpu_use = 0.0;
    
    	old_CPU_Time = (unsigned long)(first->user + first->nic + first->system + first->idle);
    	new_CPU_Time = (unsigned long)(second->user + second->nic + second->system + second->idle);
    
    	usr_Time_Diff = (unsigned long)(second->user - first->user);
    	sys_Time_Diff = (unsigned long)(second->system - first->system);
    	nic_Time_Diff = (unsigned long)(second->nic -first->nic);
    
    	if ((new_CPU_Time - old_CPU_Time) != 0)
    	  cpu_use = (float)100*(usr_Time_Diff + sys_Time_Diff + nic_Time_Diff)/(new_CPU_Time - old_CPU_Time);
    	else
    	  cpu_use = 0.0;
    	return cpu_use;
    }
    
    float
    GetHostCPURate()
    {
    	float cpu_rate;
    	SysCPUInfo *first, *second;
    	first = _GetHostCPUInfo();
    	sleep(10);
    	second = _GetHostCPUInfo();
    
    	cpu_rate = _CalculateHostCPURate(first, second);
    
    	/* clean auxiliary memory */
    	free(first);
    	free(second);
    	first = second = NULL;
    
    	return cpu_rate;
    }
    
    内存使用率

    内存使用率的计算比較方便。能够直接调用Linux系统的一个库函数sysinfo(),该函数返回例如以下的一个结构体:

    struct sysinfo {
                   long uptime;             /* Seconds since boot */
                   unsigned long loads[3];  /* 1, 5, and 15 minute load averages */
                   unsigned long totalram;  /* Total usable main memory size */
                   unsigned long freeram;   /* Available memory size */
                   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;    /* Number of current processes */
                   unsigned long totalhigh; /* Total high memory size */
                   unsigned long freehigh;  /* Available high memory size */
                   unsigned int mem_unit;   /* Memory unit size in bytes */
                   char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding for libc5 */
               };
    
    该结构体中freeram表示可用内存的大小,totalram表示总内存大小。所以通过这两个值就能够计算内存使用率了。代码实现例如以下所看到的:

    SysMemInfo *
    GetHostMemInfo()
    {
    	SysMemInfo *memInfo = (SysMemInfo *)malloc(sizeof(SysMemInfo));
    	if (NULL == memInfo)
    	  err_dump("GetMemInfo: malloc SysMemInfo Struct error");
    
    	struct sysinfo tmp;
    	int ret = 0;
    	ret = sysinfo(&tmp);
    	if (ret == 0) {
    		memInfo->MemFree = (unsigned long)tmp.freeram/(1024*1024);
    		memInfo->MemTotal = (unsigned long)tmp.totalram/(1024*1024);
    	} else {
    		err_dump("GetMemInfo: sysinfo() error");
    	}
    	return memInfo;
    }
    磁盘利用率

    本来打算通过读文件/proc/partitions来获取磁盘分区的使用情况,只是这样仅仅能够获取分区的大小。使用情况是无法获取的。只是能够通过读取文件/etc/mtab来读取系统中全部文件系统的信息。然后统计全部文件系统占用的磁盘总大小和能够磁盘的总大小,这样就能够计算出系统中文件系统的总磁盘利用率。

    代码实现例如以下所看到的:

    SysDiskInfo *
    GetHostDiskInfo()
    {
    	SysDiskInfo *sys_disk_info = (SysDiskInfo *)malloc(sizeof(SysDiskInfo));
    	DiskInfo		*disk_info;
    	struct statfs	fs_info;
    	struct mntent	*mnt_info;
    	FILE			*fh;
    	float			percent;
    	unsigned long	sum_Total = 0, total_free = 0;
    
    	if ((fh = setmntent("/etc/mtab", "r")) == NULL) {
    		printf("Cannot open /etc/mtab file!:%s
    ",strerror(errno));
    		return NULL;
    	}
    
    	while ((mnt_info = getmntent(fh)) != NULL) {
    		if (statfs(mnt_info->mnt_dir, &fs_info) < 0) {
    			continue;
    		}
    		
    		if ((disk_info = (DiskInfo *)malloc(sizeof(DiskInfo))) == NULL) {
    			continue;
    		}
    
    		if (strcmp(mnt_info->mnt_type, "proc") &&
    			strcmp(mnt_info->mnt_type, "devfs") &&
    			strcmp(mnt_info->mnt_type, "usbfs") &&
    			strcmp(mnt_info->mnt_type, "sysfs") &&
    			strcmp(mnt_info->mnt_type, "tmpfs") &&
    			strcmp(mnt_info->mnt_type, "devpts") &&
    			strcmp(mnt_info->mnt_type, "fusectl") &&
    			strcmp(mnt_info->mnt_type, "debugfs") &&
    			strcmp(mnt_info->mnt_type, "binfmt_misc") &&
    			strcmp(mnt_info->mnt_type, "fuse.gvfs_fuse_daemon")&&
    			strcmp(mnt_info->mnt_type, "securityfs")) {
    			if (fs_info.f_blocks != 0) {
    				percent = ((float)fs_info.f_blocks - (float)fs_info.f_bfree * 100.0/
    							(float)fs_info.f_blocks);
    			} else {
    				percent = 0;
    			}
    		} else {
    			continue;
    		}
    		
    		strcpy(disk_info->type, mnt_info->mnt_type);
    		strcpy(disk_info->device, mnt_info->mnt_fsname);
    		strcpy(disk_info->mntpnt, mnt_info->mnt_dir);
    
    		unsigned long block_size = fs_info.f_bsize/1024;
    		disk_info->blocks = fs_info.f_blocks * block_size / 1024;
    		disk_info->bfree = fs_info.f_bfree * block_size / 1024;
    		disk_info->availiable_disk = fs_info.f_bavail * block_size / 1024;
    		disk_info->bused = (fs_info.f_blocks - fs_info.f_bfree) * block_size / 1024;
    		disk_info->bused_percent = percent;
    		
    		sum_Total += disk_info->blocks;
    		total_free += disk_info->availiable_disk;
    
    		/* clean auxiliary memory */
    		free(disk_info);
    		disk_info = NULL;
    	}
    	sys_disk_info->Disk_Total = sum_Total/1024;
    	sys_disk_info->Disk_Free = total_free/1024;
    	return sys_disk_info;
    }





    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    iommu分析之smmu v3的实现
    关于virtio_net网卡命名的小问题
    Affinity broken due to vector space exhaustion 问题
    iommu系列之概念解释篇
    获取客户端Mac地址
    SqList *L 和 SqList * &L的区别/学习数据结构突然发现不太懂 小祥我查找总结了一下
    前端页面报表图在线js库
    MybatisPlus自动填充
    SpringBoot集成druid开启内置监控页面
    简单的系统用户权限设计图
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4710824.html
Copyright © 2011-2022 走看看