博舍

Linux下C语言获取cpu使用率 aix获取cpu使用率

Linux下C语言获取cpu使用率

一、功能介绍

通过读取/proc/stat文件获取当前系统的CPU占用率。

Linux系统上的/proc目录是一种文件系统,即proc文件系统,与其它常见的文件系统不同的是,/proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为内核与进程提供通信的接口。用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取/proc目录中的文件时,proc文件系统是动态从系统内核读出所需信息并提交的。

/proc/stat文件包含了所有CPU活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。不同内核版本中该文件的格式可能不大一致。

获取电脑实时CPU使用率

要求:实现一个计算电脑实时CPU占有率的测试程序,将多种方法获取结果显示在对话框上,动态显示。

实现:

1、新建基于对话框的MFC应用程序,Dialog上添加控件,为控件添加CSting类型变量m_RateResult1、m_RateResult2、m_RateResult3,

    

2、创建线程类(Thread.h和Thread.cpp),在####Dlg.cpp文件中的初始化函数OnInitDialog()中创建计算CPU利用率的线程

//TODO:在此添加额外的初始化代码_beginthread(&CThread::InitCalcuPdh,0,this);_beginthread(&CThread::InitCalcuGet,0,this);_beginthread(&CThread::InitCalcuNt,0,this);

3、线程类中计算CPU利用率

方式一:使用PerformanceDataHelper(PDH)性能数据助手,获取CPU利用率

1voidCThread::InitCalcuPdh(void*pDlg)2{3CCalculateCPURateDlg*pItemDlg=(CCalculateCPURateDlg*)pDlg;4if(pItemDlg==NULL)5{6return;7}89while(1)10{11//打开查询(query)句柄12HQUERYquery;13PDH_STATUSstatus=PdhOpenQuery(NULL,NULL,&query);14if(status!=ERROR_SUCCESS)15{16pItemDlg->MessageBox(L"OpenQueryError",NULL,MB_OK);17continue;18}1920//在查询中加入计数器(counter)21HCOUNTERcounter;22//counter=(HCOUNTER*)GlobalAlloc(GPTR,sizeof(HCOUNTER));23status=PdhAddCounter(query,LPCWSTR(L"\ProcessorInformation(_Total)\%ProcessorTime"),NULL,&counter);24if(status!=ERROR_SUCCESS)25{26pItemDlg->MessageBox(L"AddCounterError",NULL,MB_OK);27continue;28}2930//收集query的数据,在两条PdhCollectQueryData()语句之间加入一条Sleep(1000)语句31PdhCollectQueryData(query);32Sleep(1000);33PdhCollectQueryData(query);3435//获得格式化(可以显示的)数据36PDH_FMT_COUNTERVALUEpdhValue;37DWORDdwValue;38status=PdhGetFormattedCounterValue(counter,PDH_FMT_DOUBLE,&dwValue,&pdhValue);39if(status!=ERROR_SUCCESS)40{41pItemDlg->MessageBox(L"GetValueError",NULL,MB_OK);42continue;43}44pItemDlg->m_RateResult1.Format(L"%.0lf%%",pdhValue.doubleValue);4546SendMessage(pItemDlg->m_hWnd,WM_UPDATEDATA,FALSE,FALSE);47PdhCloseQuery(query);48}49}

方式二:使用windows自带的API(GetSystemTimes)获取CPU利用率

1__int64DiffFileTime(FILETIMEtime1,FILETIMEtime2)2{3__int64a=time1.dwHighDateTimem_hWnd,WM_UPDATEDATA,FALSE,FALSE);39}40}

方式三:使用windowsAPI(NtQuerySystemInformation)获取CPU利用率

1typedefstruct_UINT64_DELTA2{3ULONG64Value;4ULONG64Delta;5}UINT64_DELTA,*PUINT64_DELTA;67#defineUpdateDelta(DltMgr,NewValue)8((DltMgr)->Delta=(NewValue)-(DltMgr)->Value,9(DltMgr)->Value=(NewValue),(DltMgr)->Delta)1011voidCThread::InitCalcuNt(void*pDlg)12{13CCalculateCPURateDlg*pItemDlg=(CCalculateCPURateDlg*)pDlg;14if(pItemDlg==NULL)15{16return;17}1819while(1)20{21doublecpu_rate;22ULONG64total_time=0;23ULONG64sys_time=0;24staticSYSTEM_PROCESSOR_PERFORMANCE_INFORMATIONCpuInformation[1024];25staticSYSTEM_INFOsys_info;2627staticUINT64_DELTAcpu_kernel_delta;28staticUINT64_DELTAcpu_user_delta;29staticUINT64_DELTAcpu_idle_delta;30staticSYSTEM_PROCESSOR_PERFORMANCE_INFORMATIONcpu_totals;31memset(&cpu_totals,0,sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));3233GetSystemInfo(&sys_info);3435NtQuerySystemInformation(36SystemProcessorPerformanceInformation,37&CpuInformation,38sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)*(ULONG)sys_info.dwNumberOfProcessors,39NULL40);4142for(inti=0;im_RateResult3.Format(L"%.0lf%%",cpu_rate);72Sleep(1000);7374SendMessage(pItemDlg->m_hWnd,WM_UPDATEDATA,FALSE,FALSE);75}76}

4、stdafx.h中添加

#pragmacomment(lib,"pdh.lib")#pragmacomment(lib,"ntdll.lib")#include#include#include#include

 

 

错误:

1、在线程中调用UpdateData函数,在Debug模式下编译可以通过,但运行时会触发中断

原因:MFC对象不支持多线程操作,不能供多个线程进程使用。子线程调用pDlg->UpdateData(FALSE)时主线程(界面线程)会阻塞,更新必须由它完成,这样就形成死锁。更改界面的操作最好用主线程(界面线程),要想在子线程(工作线程)里执行界面的操作,可以通过向主线程发送消息来解决。

解决:

####Dlg.h中添加

#defineWM_UPDATEDATA10000+1afx_msgLRESULTOnUpdateData(WPARAMwParam,LPARAMlParam);

####Dlg.cpp中添加

ON_MESSAGE(WM_UPDATEDATA,OnUpdateData)LRESULTCCalculateCPURateDlg::OnUpdateData(WPARAMwParam,LPARAMlParam){UpdateData(wParam);return0;}

Thread.cpp中添加

SendMessage(pItemDlg->m_hWnd,WM_UPDATEDATA,FALSE,FALSE);

2、在某些环境中exe文件运行失败

解决:Release使用MT选项编译,Debug使用MTd选项编译(同时属性页中选择在静态库中使用MFC)

 

参考博客:

https://www.cnblogs.com/einyboy/archive/2012/06/13/2548243.html

http://www.cnblogs.com/hbccdf/p/get_sys_cpu_usage_and_mem_usage.html

 

C++获取CPU使用率

1、使用Ntdll.dll函数

NTSTATUSWINAPINtQuerySystemInformation(

_In_       SYSTEM_INFORMATION_CLASSSystemInformationClass,_Inout_    PVOIDSystemInformation,_In_       ULONGSystemInformationLength,_Out_opt_  PULONGReturnLength);

计算CPU使用率的方法为查询SystemBasicInformation和SystemPerformanceInformation两个参数进行计算。

SYSTEM_BASIC_INFORMATION

Whenthe SystemInformationClass parameteris SystemBasicInformation,thebufferpointedtobythe SystemInformation parametershouldbelargeenoughtoholdasingleSYSTEM_BASIC_INFORMATION structurehavingthefollowinglayout:

typedefstruct_SYSTEM_BASIC_INFORMATION{BYTEReserved1[24];PVOIDReserved2[4];CCHARNumberOfProcessors;}SYSTEM_BASIC_INFORMATION;

The NumberOfProcessors membercontainsthenumberofprocessorspresentinthesystem.Use GetSystemInfo insteadtoretrievethisinformation.

Theothermembersofthestructurearereservedforinternalusebytheoperatingsystem.

SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION

Whenthe SystemInformationClass parameteris SystemProcessorPerformanceInformation,thebufferpointedtobythe SystemInformation parametershouldbelargeenoughtoholdanarraythatcontainsasmany SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION structuresasthereareprocessors(CPUs)installedinthesystem.Eachstructurehasthefollowinglayout:

typedefstruct_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION{LARGE_INTEGERIdleTime;LARGE_INTEGERKernelTime;LARGE_INTEGERUserTime;LARGE_INTEGERReserved1[2];ULONGReserved2;}SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;

The IdleTime membercontainstheamountoftimethatthesystemhasbeenidle,in100-nanosecondintervals.

The KernelTime membercontainstheamountoftimethatthesystemhasspentexecutinginKernelmode(includingallthreadsinallprocesses,onallprocessors),in100-nanosecondintervals.

The UserTime membercontainstheamountoftimethatthesystemhasspentexecutinginUsermode(includingallthreadsinallprocesses,onallprocessors),in100-nanosecondintervals.

Use GetSystemTimes insteadtoretrievethisinformation.

Remarks

The NtQuerySystemInformation functionandthestructuresthatitreturnsareinternaltotheoperatingsystemandsubjecttochangefromonereleaseofWindowstoanother.Tomaintainthecompatibilityofyourapplication,itisbettertousethealternatefunctionspreviouslymentionedinstead.

Ifyoudouse NtQuerySystemInformation,accessthefunctionthrough run-timedynamiclinking.Thisgivesyourcodeanopportunitytorespondgracefullyifthefunctionhasbeenchangedorremovedfromtheoperatingsystem.Signaturechanges,however,maynotbedetectable.

Thisfunctionhasnoassociatedimportlibrary.Youmustusethe LoadLibrary and GetProcAddress functionstodynamicallylinktoNtdll.dll.

使用该函数必须动态加载Ntdll.dll库和导出函数,使用起来比较麻烦。微软在XPsp1以后提供了新的API接口函数。

上述两个参数可分别使用GetSystemInfo和GetSystemTimes函数代替。

详情参看MSDN:http://msdn.microsoft.com/en-us/library/ms724509.aspx

具体实现方法可以百度。

2、使用GetSystemTimes函数

//GetCpuUseage.h#includeclassGetCpuUseage{public:GetCpuUseage();~GetCpuUseage();public:doubleCpuUseage();private:FILETIMEm_preidleTime;FILETIMEm_prekernelTime;FILETIMEm_preuserTime;};

//GetCpuUseage.cpp#include"stdafx.h"#include"GetCpuUseage.h"__int64CompareFileTime(FILETIMEtime1,FILETIMEtime2){__int64a=time1.dwHighDateTime}doubleGetCpuUseage::CpuUseage(){FILETIMEidleTime;FILETIMEkernelTime;FILETIMEuserTime;GetSystemTimes(&idleTime,&kernelTime,&userTime);intidle=CompareFileTime(m_preidleTime,idleTime);intkernel=CompareFileTime(m_prekernelTime,kernelTime);intuser=CompareFileTime(m_preuserTime,userTime);if(kernel+user==0)return0.0;//(总的时间-空闲时间)/总的时间=占用cpu的时间就是使用率doublecpu=(kernel+user-idle)*100/(kernel+user);m_preidleTime=idleTime;m_prekernelTime=kernelTime;m_preuserTime=userTime;returncpu;}

调用方法:

#include"GetCpuUseage.h"

#include

intmain()

{

GetCpuUseagegetCpuUseage;

while(true)

{

printf("CPU使用率:%0.2f ",getCpuUseage.CpuUseage());

sleep(1000);

}

return0;

}

java应用cpu使用率过高问题排查

---------------------------------------linux下如何定位代码问题-------------------------------

1、先通过top命令找到消耗cpu很高的进程id假设是123

2、执行top-p123单独监控该进程

3、在第2步的监控界面输入H,获取当前进程下的所有线程信息

4、找到消耗cpu特别高的线程编号,假设是123

5、执行jstack123456对当前的进程做dump,输出所有的线程信息

6 将第4步得到的线程编号11354转成16进制是0x7b

7 根据第6步得到的0x7b在第5步的线程信息里面去找对应线程内容

8 解读线程信息,定位具体代码位置

-----------------------------分割线----------------------------------------------

 

最近在压力测试工作中碰到java应用某台机器cpu比较高的情况,特地下笔记以后总结:

一个简单的淘宝认证接口需要插入读写数据库2次。每次爬取数据,入库。完成。

正常情况下:

应用使用cpu在:50%--80%

压力高--异常情况下:

cpu利用率在:90%---90%

在网上查了下,一般java应用cpu过高基本上是因为

1.程序计算比较密集

2.程序死循环

3.程序逻请求堵塞4.IO读写太高 

方法一:

分析步骤:

1.登陆应用机器,top-d1命令查看当前占用cpu资源最多的,一般排名第一位肯定是java进程

一般也可能存在多个java进程 

 

观察top消耗第一的资源是PID=1679的线程

2.查看进程的哪个线程占用cpu比较高,取线上另外一台正常情况下利用cpu比较高的应用:通过

ps-mppid-oTHREAD,tid,time命令查看该进程的线程情况

通过以上线程CPU切片耗时在pid=1679Tid=1896耗时1分59秒,4%CPU占用最大。时间最长。

TID为1679的线程利用cpu资源比较多,怎么能看到这个线程在干什么呢?

需要将1896 转换为16进制,便于在jvm堆栈中查找。

printf"%x "1896 ----768

通过jstack命令来查看下当前内存状态:

 定位到cpu过高是IO读写太高,接下来就是找开发人员确认这段代码是否可以优化。

 

方法二:

在做压测的时候,开发给了一个工具 show-busy-java-threads.sh

在排查Java的CPU性能问题时,找出Java进程中消耗cpu多(topus值过高)的线程,查看它的线程栈,从而找出有性能问题的方法调用。

####截取一段

#!/bin/bash#@Function#Findoutthehighestcpuconsumedthreadsofjava,andprintthestackofthesethreads.##@Usage#$./show-busy-java-threads.sh##@authorJerryLeereadonlyPROG=`basename$0`readonly-aCOMMAND_LINE=("$0""$@")usage(){cat

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

上一篇

下一篇