ubuntu 利用proc 文件系统实现监听器

proc文件系统特定文件的关系

获取并显示主机名/proc/sys/kernel/hostname
获取并显示系统时间/proc/uptime
当前内存使用情况/proc/meminfo
显示系统的版本号/proc/sys/kernel/ostype ,
           /proc/sys/kernel/osrelease
显示cpu信息/proc/cpuinfo
  
显示系统所有进程的一些信息,包括pid,ppid,占用内存大小,优先级等等/proc/(pid)/stat,
              /proc/(pid)/statm
cpu使用率的图形化显示(2分钟内的历史纪录曲线)/proc/stat
内存和交换分区(swap)使用率的图形化显示(2分钟内的历史纪录曲线)/proc/meminfo
  
在状态栏显示当前cpu使用率/proc/stat



2.获取CPU使用率

在/proc/stat文件里获取相关信息,再利用相关算法计算出利用率,直接上代码

float MainWindow::CPU_usage(){
            FILE *fp;
            char buf[128];
            char cpu[5];
            static long int static_all=0;
            static long int static_idle=0;
            long int user,nice,sys,idle,iowait,irq,softirq;

            long int all1,idle1;
            float usage;

                    fp = fopen("/proc/stat","r");
                    if(fp == NULL)
                    {
                            perror("fopen:");
                            exit (0);
                    }


                    fgets(buf,sizeof(buf),fp);
                    sscanf(buf,"%s%d%d%d%d%d%d%d",cpu,&user,&nice,&sys,&idle,&iowait,&irq,&softirq);
                    /*
    #if __DEBUG__
    printf("%s,%d,%d,%d,%d,%d,%d,%d\n",cpu,user,nice,sys,idle,iowait,irq,softirq);
    #endif
    */
                    all1 = user+nice+sys+idle+iowait+irq+softirq;
                    idle1 = idle;

                    usage = (float)(all1-static_all-(idle1-static_idle)) / (all1-static_all)*100 ;

                    static_all=all1;
                    static_idle=idle1;

                    fclose(fp);
             return usage;
}

3.获取内存利用率和swap利用率

MemInfoStruct MainWindow::Mem_usage(){
            FILE *fp;
            char buf[128];
            char titlename[10];
            char kb[3];
            long int memtotal,memactive,SwapTotal,SwapFree;

            MemInfoStruct str;
            float usage,SwapUsage;

                    fp = fopen("/proc/meminfo","r");
                    if(fp == NULL)
                    {
                            perror("fopen:");
                            exit (0);
                    }
                    for(int i=0;i<16;i++){
                        fgets(buf,sizeof(buf),fp);
                        qDebug()<<buf<<"end";
                        if(i==0){   //get memtotal
                            sscanf(buf,"%s%ld%s",titlename,&memtotal,kb);

                        }

                        else if(i==6){   //get memactive
                            sscanf(buf,"%s%ld%s",titlename,&memactive,kb);

                        }
                        else if(i==14){   //get memactive
                            sscanf(buf,"%s%ld%s",titlename,&SwapTotal,kb);

                        }
                        else if(i==15){   //get memactive
                            sscanf(buf,"%s%ld%s",titlename,&SwapFree,kb);

                        }
                    }
                    usage=(float)memactive/memtotal*100;
                    SwapUsage=(float)(SwapTotal-SwapFree)/SwapTotal;
                    str.Mem_usage=usage;
                    str.swap_usage=SwapUsage;
             return str;
}


以上函数中返回值是一个包含内存利用率和swap利用率的结构体

struct MemInfoStruct
{
    float Mem_usage;
    float swap_usage;
};

4.返回os信息

const QString MainWindow::ret_osinfo(){
    FILE *fp;
    fp = fopen("/proc/sys/kernel/ostype","r");
    char buf_type[10],buf_release[20];
    if(fp==NULL){
        perror("fopen:");
        exit(0);
    }
    fgets(buf_type,sizeof(buf_type),fp);
    fclose(fp);
    fp=fopen("/proc/sys/kernel/osrelease","r");
    if(fp==NULL){
        perror("fopen:");
        exit(0);
    }
    fgets(buf_release,sizeof(buf_release),fp);
    QString ret_str=QString("%1 %2").arg(buf_type,buf_release);
    ret_str.replace("\n","");
    return ret_str;
}

5.获取时间有关的信息

//activate Time&Run Time
    QString myText =openFIleReturnString("/proc/uptime");
    QString tempText=myText;
    myText="activate Time:"+myText.remove(myText.indexOf(" ",0),10);
    ui->activateTimelabel->setText(myText);
    tempText="Run Time:"+tempText.remove(0,myText.indexOf(" ",0));
    tempText=tempText.remove(tempText.size()-1,1);

    ui->RunTimelabel->setText(tempText);

    //current Time
    QDateTime current_date_time =QDateTime::currentDateTime();
    QString current_date =current_date_time.toString("yyyy.MM.dd hh:mm:ss.zzz ddd");
    ui->CurrentTimelabel->setText(current_date);

2.获取进程相关信息和相关操作

1.获取/proc文件夹中的所以文件名以用于获取每一个进程文件

vector<string> ps::getFiles(string cate_dir)
{
    vector<string> files;//存放文件名

    DIR *dir;
    struct dirent *ptr;
    char base[1000];

    if ((dir=opendir(cate_dir.c_str())) == NULL)
        {
        perror("Open dir error...");
                exit(1);
        }

    while ((ptr=readdir(dir)) != NULL)
    {
        if(strcmp(ptr->d_name,".")==0 || strcmp(ptr->d_name,"..")==0)    ///current dir OR parrent dir
                continue;
        else if(ptr->d_type == 8)    ///file
            //printf("d_name:%s/%s\n",basePath,ptr->d_name);
            files.push_back(ptr->d_name);
        else if(ptr->d_type == 10)    ///link file
            //printf("d_name:%s/%s\n",basePath,ptr->d_name);
            continue;
        else if(ptr->d_type == 4)    ///dir
        {
            files.push_back(ptr->d_name);
        }
    }
    closedir(dir);

    //排序,按从小到大排序
    sort(files.begin(), files.end());
    return files;
} 

2.依次打开获取的文件,把进程信息显示在tablewidget当中

void ps::timerUpdate(){
    FILE *fp;
    char name[25],scan_temp[25];

    string basePath="/proc";
    vector<string> files=getFiles(basePath);
//    for (int i=0; i<files.size(); i++)
//    {
//        cout<<files[i]<<endl;
//    }

//    cout<<"end..."<<endl<<endl;


    //set rowCount of table widget
    ui->tableWidget->setRowCount(files.size());
    int rowcounter=0;

    for(int i=0;i<files.size();i++){


        int pid,priority,rss,ppid;
        string temp="/proc/"+files[i]+"/stat";
        fp=fopen(temp.data(),"r");
        if(fp == NULL)   //when pros by kill
        {
            continue;
        }
        else rowcounter++;


        if(rowcounter>rowcounter_old) {
            ui->tableWidget->setRowCount(files.size());
            rowcounter_old=files.size();
        }

//        fgets(buf,sizeof(buf),fp);
//        qDebug()<<buf;
        for(int j=0;j<25;j++){
            if(j==0) fscanf(fp,"%d",&pid);
            else if(j==1) fscanf(fp,"%s",name);
            else if(j==3) fscanf(fp,"%d",&ppid);
            else if(j==17) fscanf(fp,"%d",&priority);
            //else if(j==23) fscanf(fp,"%d",&rss);
            else fscanf(fp,"%s",scan_temp);
        }
        fclose(fp);
        temp=temp+"m";
        fp=fopen(temp.data(),"r");
        if(fp == NULL)   //when pros by kill
        {
            continue;
        }

        fscanf(fp,"%s%d",scan_temp,&rss);
        rss=rss*4;
        fclose(fp);
        //qDebug()<<name<<pid<<ppid<<priority<<rss;


        //insert in listWidget
          QTableWidgetItem *item = new QTableWidgetItem();
          QTableWidgetItem *item1 = new QTableWidgetItem();
          QTableWidgetItem *item2 = new QTableWidgetItem();
          QTableWidgetItem *item3 = new QTableWidgetItem();
          QTableWidgetItem *item4 = new QTableWidgetItem();
          item->setText(QString(name).remove("(").remove(")"));

          item1->setText(QString::number(pid,10));
          item2->setText(QString::number(ppid,10));
          item3->setText(QString::number(rss,10));
          item4->setText(QString::number(priority,10));

          ui->tableWidget->setItem(i, 0, item);
          ui->tableWidget->setItem(i, 1, item1);
            ui->tableWidget->setItem(i, 2, item2);
            ui->tableWidget->setItem(i, 3, item3);
            ui->tableWidget->setItem(i, 4, item4);

    }
    ui->tableWidget->setRowCount(rowcounter);
    rowcounter_old=rowcounter;


}

每隔1s更新上面函数

3.选中tablewidget中的一行并杀死那一行所在的进程

void ps::clickedKillPushButton()
{
    if(ui->tableWidget->selectedItems().isEmpty()) return;
    QMessageBox::StandardButton rb = QMessageBox::question(NULL, "Warning", "this maybe  will broke your system,are you sure to continue?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
    if(rb == QMessageBox::Yes)
    {
        QList<QTableWidgetItem*> items = ui->tableWidget->selectedItems();
        QTableWidgetItem *item = items.at(1);
        int pid=item->text().toInt();
        kill(pid,SIGKILL);  //kill ps
    }


}

4.查看选中一行的进程信息

void ps::clickedInfoPushButton()
{
    if(ui->tableWidget->selectedItems().isEmpty()) return;
    QList<QTableWidgetItem*> items = ui->tableWidget->selectedItems();
    QTableWidgetItem *item = items.at(1);
    int pid=item->text().toInt();
    char datapath[30];
    sprintf(datapath,"/proc/%d/status",pid);
    //qDebug()<<datapath;
    FILE *fp;
    fp=fopen(datapath,"r");
    QString infoStr;
    char buf[128];
    while(!feof(fp)){
    fgets(buf,sizeof(buf),fp);
    infoStr+=buf;
    }
    QMessageBox::information(this,"information",infoStr);
}

5.查询pid或者进程名并定位到那一行

void ps::clickedSearchPushButton()
{
    QString text=ui->searchlineEdit->text();
    if(text.isEmpty()) return;
    for(int i=0;i<rowcounter_old;i++){
        if(ui->tableWidget->item(i,0)->text()==text||ui->tableWidget->item(i,1)->text()==text){
            ui->tableWidget->selectRow(i);
            break;
        }
    }
}

3.绘制cpu和内存监控特效

懒得解释了直接上代码吧,每隔1s更新clockwidget类中的usage_value即可

//clockwidget.cpp
#include "clockwidget.h"
#include "ui_clockwidget.h"
#include <QTimer>
#include <qmath.h>
#include <QTime>
#include <QPainter>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <unistd.h>

clockWidget::clockWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::clockWidget)
{
    ui->setupUi(this);
    usage_value=0;
    QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(update()));
        timer->start(1000);
}

clockWidget::~clockWidget()
{
    delete ui;
}


QRectF clockWidget::textRectF(double radius, int pointSize, double angle)
{
    QRectF rectF;
    rectF.setX(radius*qCos(angle*3.14/180.0) - pointSize*2);
    rectF.setY(radius*qSin(angle*3.14/180.0) - pointSize/2.0);
    rectF.setWidth(pointSize*4);
    rectF.setHeight(pointSize);
    return rectF;
}


void clockWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    // 针位置 - 多边形
    static const QPoint hourHand[3] = {
        QPoint(7, 8),
        QPoint(-7, 8),
        QPoint(0, -30)
    };
    static const QPoint minuteHand[3] = {
        QPoint(7, 8),
        QPoint(-7, 8),
        QPoint(0, -65)
    };

    static const QPoint secondHand[3] = {
        QPoint(7, 8),
        QPoint(-7, 8),
        QPoint(0, -80)
    };

    // 针颜色
    QColor hourColor(200, 100, 0, 200);
    QColor minuteColor(0, 127, 127, 150);
    QColor secondColor(0, 160, 230, 150);

    int side = qMin(width(), height());
    QTime time = QTime::currentTime();

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    // 平移坐标系原点至中心点
    painter.translate(width() / 2, height() / 2);
    // 缩放
    painter.scale(side / 200.0, side / 200.0);

    // 绘制时针
    painter.setPen(Qt::NoPen);
    painter.setBrush(hourColor);

    painter.save();
    // 每圈360° = 12h 即:旋转角度 = 小时数 * 30°
    painter.restore();

    painter.setPen(hourColor);

    // 绘制小时线 (360度 / 12 = 30度)
    for (int i = 0; i < 12; ++i) {
        painter.drawLine(88, 0, 96, 0);
        painter.rotate(30.0);
    }

    int radius = 100;
    QFont font = painter.font();
    font.setBold(true);
    painter.setFont(font);
    int pointSize = font.pointSize();

    // 绘制小时文本
    int nHour = 0;
    for (int i = 0; i < 11; ++i) {
        nHour = i ;
//        if (nHour > 10)
//            nHour -= 10;
        painter.drawText(textRectF(radius*0.8, pointSize, (i+4) * 30), Qt::AlignCenter, QString::number(nHour*10));
    }

    // 绘制分针
    painter.setPen(Qt::NoPen);
    painter.setBrush(minuteColor);

    painter.save();
    // 每圈360° = 60m 即:旋转角度 = 分钟数 * 6°
    painter.restore();

    painter.setPen(minuteColor);

    // 绘制分钟线 (360度 / 60 = 6度)
    for (int j = 0; j < 60; ++j) {
        if ((j % 5) != 0)
            painter.drawLine(92, 0, 96, 0);
        painter.rotate(6.0);
    }

    // 绘制秒针
    painter.setPen(Qt::NoPen);
    painter.setBrush(secondColor);

    painter.save();
    // 每圈360° = 60s 即:旋转角度 = 秒数 * 6°
    painter.rotate((float)300/100 * usage_value-150);         //input how %
    painter.drawConvexPolygon(secondHand, 3);
    painter.restore();
}

void clockWidget::set_usage(float usage){
    usage_value=usage;
}

4.画历史曲线

利用QT插件qcustomplot画曲线很方便,qcustomplot的用法如下

从网上下载qcustomplot.h 和qcustomplot.cpp

加载到工程中 改.pro文件 第9行末加上 printsupport 即可,再编译一下没有报错就可以用

//graph.cpp
#include "graph.h"
#include "ui_graph.h"
#include <QVector>

#include <QTime>
#include <QTimer>
#include <time.h>

Graph::Graph(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Graph)
{
    ui->setupUi(this);

    QLinearGradient plotGradient;
    //lotGradient.setStart(0, 0);
    //plotGradient.setFinalStop(0, 350);
    plotGradient.setColorAt(0, QColor(80, 80, 80));
    //plotGradient.setColorAt(1, QColor(50, 50, 50));
    ui->widget->setBackground(plotGradient);

   //设置坐标颜色/坐标名称颜色
    ui->widget->xAxis->setLabelColor(Qt::white);//文字颜色
    ui->widget->yAxis->setLabelColor(Qt::white);
    ui->widget->xAxis->setTickLabelColor(Qt::white);//坐标轴数字颜色
    ui->widget->yAxis->setTickLabelColor(Qt::white);
    ui->widget->xAxis->setBasePen(QPen(Qt::white, 1));//坐标轴颜色及宽度
    ui->widget->yAxis->setBasePen(QPen(Qt::white, 1));
    ui->widget->xAxis->setTickPen(QPen(Qt::white, 1));//主刻度
    ui->widget->yAxis->setTickPen(QPen(Qt::white, 1));
    ui->widget->xAxis->setSubTickPen(QPen(Qt::white, 1));//副刻度
    ui->widget->yAxis->setSubTickPen(QPen(Qt::white, 1));


    //设置属性可缩放,移动等
    ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes |
                                         QCP::iSelectLegend | QCP::iSelectPlottables);


    ui->Memwidget->setBackground(plotGradient);

   //设置坐标颜色/坐标名称颜色
    ui->Memwidget->xAxis->setLabelColor(Qt::white);//文字颜色
    ui->Memwidget->yAxis->setLabelColor(Qt::white);
    ui->Memwidget->xAxis->setTickLabelColor(Qt::white);//坐标轴数字颜色
    ui->Memwidget->yAxis->setTickLabelColor(Qt::white);
    ui->Memwidget->xAxis->setBasePen(QPen(Qt::white, 1));//坐标轴颜色及宽度
    ui->Memwidget->yAxis->setBasePen(QPen(Qt::white, 1));
    ui->Memwidget->xAxis->setTickPen(QPen(Qt::white, 1));//主刻度
    ui->Memwidget->yAxis->setTickPen(QPen(Qt::white, 1));
    ui->Memwidget->xAxis->setSubTickPen(QPen(Qt::white, 1));//副刻度
    ui->Memwidget->yAxis->setSubTickPen(QPen(Qt::white, 1));


    //设置属性可缩放,移动等
    ui->Memwidget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes |
                                         QCP::iSelectLegend | QCP::iSelectPlottables);


    ui->Swapwidget->setBackground(plotGradient);
    ui->Swapwidget->xAxis->setLabelColor(Qt::white);//文字颜色
    ui->Swapwidget->yAxis->setLabelColor(Qt::white);
    ui->Swapwidget->xAxis->setTickLabelColor(Qt::white);//坐标轴数字颜色
    ui->Swapwidget->yAxis->setTickLabelColor(Qt::white);
    ui->Swapwidget->xAxis->setBasePen(QPen(Qt::white, 1));//坐标轴颜色及宽度
    ui->Swapwidget->yAxis->setBasePen(QPen(Qt::white, 1));
    ui->Swapwidget->xAxis->setTickPen(QPen(Qt::white, 1));//主刻度
    ui->Swapwidget->yAxis->setTickPen(QPen(Qt::white, 1));
    ui->Swapwidget->xAxis->setSubTickPen(QPen(Qt::white, 1));//副刻度
    ui->Swapwidget->yAxis->setSubTickPen(QPen(Qt::white, 1));


    //设置属性可缩放,移动等
    ui->Swapwidget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes |
                                         QCP::iSelectLegend | QCP::iSelectPlottables);

    connect(ui->RePaintButton,SIGNAL(clicked(bool)),this,SLOT(RePaint()));
}

Graph::~Graph()
{
    delete ui;
}

void Graph::Graph_Show(QCustomPlot *CustomPlot,QVector<double> data)
{
        QVector<double> temp(20);
        for(int i=0;i<20;i++) temp[i]=i;
       //设置画布颜色



        CustomPlot->addGraph();//添加一条曲线
        CustomPlot->graph(0)->setPen(QPen(Qt::green)); //0是曲线序号,添加的第一条是0,设置曲线颜色
        CustomPlot->graph(0)->setData(temp,data); //输出各点的图像,x和y都是QVector类


        CustomPlot->xAxis->setRange(0,20);//x轴范围
        CustomPlot->yAxis->setRange(0,100);//y轴范围
        CustomPlot->replot();//重绘
}

void Graph::Graph_Show(double cpu_usage,MemInfoStruct str)
{
     CPUusage.append(cpu_usage);
     if(CPUusage.size()>20) CPUusage.removeFirst();
     Graph_Show(ui->widget,CPUusage);

     Memusage.append(str.Mem_usage);
     if(Memusage.size()>20) Memusage.removeFirst();
     Graph_Show(ui->Memwidget,Memusage);

     Swapusage.append(str.swap_usage);
     if(Swapusage.size()>20) Swapusage.removeFirst();
     Graph_Show(ui->Swapwidget,Swapusage);
}

void Graph::RePaint()
{
    CPUusage.clear();
    Memusage.clear();
    Swapusage.clear();
}

5.主窗口中的其他功能

void MainWindow::clicked_PowerOffAction()
{
    QMessageBox::StandardButton rb = QMessageBox::question(NULL, "Warning", "this will let your system power off,are you sure to continue?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
    if(rb == QMessageBox::Yes)
    {
        system("poweroff");
    }
}

void MainWindow::clicked_NewProgressAction()
{
    QString file_name = QFileDialog::getOpenFileName(NULL,"Open New Progress",".","*");
    file_name="cd / \n"+file_name+" &";
    qDebug()<<file_name;
    QByteArray ba = file_name.toLatin1(); // must
    system(ba.data());

}
以上就是监控器的组成了,具体代码从 http://download.csdn.net/download/arafatms/10273184下载
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值