ubuntu 利用proc 文件系统实现监听器
2018-03-07 11:28
656 查看
proc文件系统特定文件的关系
2.获取CPU使用率
在/proc/stat文件里获取相关信息,再利用相关算法计算出利用率,直接上代码
3.获取内存利用率和swap利用率
以上函数中返回值是一个包含内存利用率和swap利用率的结构体
4.返回os信息
5.获取时间有关的信息
2.获取进程相关信息和相关操作
1.获取/proc文件夹中的所以文件名以用于获取每一个进程文件
2.依次打开获取的文件,把进程信息显示在tablewidget当中
每隔1s更新上面函数
3.选中tablewidget中的一行并杀死那一行所在的进程
4.查看选中一行的进程信息
5.查询pid或者进程名并定位到那一行
3.绘制cpu和内存监控特效
懒得解释了直接上代码吧,每隔1s更新clockwidget类中的usage_value即可
4.画历史曲线
利用QT插件qcustomplot画曲线很方便,qcustomplot的用法如下
从网上下载qcustomplot.h 和qcustomplot.cpp
加载到工程中 改.pro文件 第9行末加上 printsupport 即可,再编译一下没有报错就可以用
5.主窗口中的其他功能
以上就是监控器的组成了,具体代码从 http://download.csdn.net/download/arafatms/10273184下载
获取并显示主机名 | /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) c42e { 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下载
相关文章推荐
- 浅析proc文件系统的创建和create_proc_read_entry函数的具体实现
- Win7系统下利用U盘安装Ubuntu_12.04实现双系统教程
- 利用Samba服务器,实现windows7下和Ubuntu文件的共享
- 不同系统平台之间(Linux与Linux、Linux与Unix)利用NFS实现文件共享方法
- UBUNTU10.04利用NFS文件系统挂载ARM S3C2440根目录
- Unix 系统(Ubuntu) 下装samba 实现文件共享(常用于windows和Unix下文件共享)
- 利用虚拟光驱实现 将WINDOWS文件供虚拟机中的UBUNTU共享
- 利用samba实现Ubuntu和win7文件共享配置过程
- 实现主机的XP系统和虚拟机的ubuntu系统的文件共享
- 利用SSH Filesystem实现远程文件系统
- Windows下利用BCD引导ubuntu实现双系统无缝切换
- 利用系统Bug来实现隐藏和保护重要文件
- 利用虚拟光驱实现 将WINDOWS文件供虚拟机中的UBUNTU共享
- 浅析proc文件系统的创建和create_proc_read_entry函数的具体实现
- 利用资源文件实现多语言的系统
- proc文件系统的实现
- Ubuntu下通过sftp远程登录linux系统,并实现上传、下载文件
- UBUNTU10.04利用NFS文件系统挂载ARM S3C2440根目录
- Ubuntu下通过sftp远程登录linux系统,并实现上传、下载文件
- 哈工大操作系统试验 7 proc文件系统的实现