




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
.。設備驅動程序安裝makeclean,清除make產生的殘留make,重新調用Makefile編譯設備驅動程序insmod-fMyDeviceDriver.ko,加載生成的MyDeviceDriver.ko模塊cat/proc/devices,獲取設備驅動程序的主設備號⑤mknod/dev/MyDeviceDriverc2500,創(chuàng)建設備文件,250為主設備號,0為從設備號測試驅動程序此設備驅動程序實現(xiàn)的功能是將一個字符串中內容拷貝到另外一個字符串中。測試程序編寫完成后,在終端輸入gcctest.c-otest進行編譯。測試結果如下:詳細代碼見REF_Ref416435358\r\h。源代碼設備驅動程序#include<linux/module.h>#include<linux/types.h>#include<linux/fs.h>#include<linux/sched.h>#include<linux/init.h>#include<linux/cdev.h>#include<linux/slab.h>#include<asm/uaccess.h>#defineDEV_SIZE102400//設備申請的最大內存空間structDevice{char*data;//數(shù)組指針,用于存放從用戶讀入的數(shù)據(jù)longsize;//存儲的數(shù)據(jù)長度}*devp;structcdevcdev;//字符設備結構體staticintdevNum_major=0;//主設備號變量//對應用戶態(tài)的lseekstaticloff_tmy_llseek<structfile*file,loff_toffset,intwhence>{ loff_tcfo=0;//文件當前偏移量,currentfileoffsetswitch<whence>{case0://SEEK_SETcfo=offset;break; case1://SEEK_CURcfo=file->f_pos+offset;break; case2://SEEK_ENDcfo=DEV_SIZE-1+offset;break;}if<<cfo<0>||<cfo>DEV_SIZE>>//文件偏移量越界 return-EINVAL;file->f_pos=cfo;returncfo;}//對應用戶態(tài)的read,寫數(shù)據(jù)到用戶空間staticssize_tmy_read<structfile*file,char__user*buf,size_tcount,loff_t*p_cfo>{ intval=0; structDevice*dev=file->private_data;//設備描述結構體指針,獲取設備信息 if<copy_to_user<buf,<void*><dev->data+*p_cfo>,count>>//如果成功返回0;如果失敗,返回未完成copy的長度 val=-EFAULT; else { *p_cfo+=count;//copy成功,文件偏移量加上count val=count; } returnval;}//對應用戶態(tài)的write,從用戶空間讀入數(shù)據(jù)staticssize_tmy_write<structfile*file,constchar__user*buf,size_tcount,loff_t*p_cfo>{ intval=0; structDevice*dev=file->private_data; if<copy_from_user<dev->data+*p_cfo,buf,count>>//如果成功返回0;如果失敗,返回未完成copy的長度 val=-EFAULT; else { *p_cfo+=count;//copy成功,文件偏移量加上count val=count; } returnval;}staticintmy_open<structinode*inode,structfile*file>{file->private_data=devp;return0;}structfile_operationsfops={ .owner=THIS_MODULE, .llseek=my_llseek, .read=my_read, .write=my_write, .open=my_open,};intinit_module<void>{ intdev_num; dev_num=register_chrdev<0,"MyDeviceDriver",&fops>; if<dev_num<0>{ printk<KERN_INFO"MyDeviceDriver:FAILtogetmajornumber\n">; returndev_num; } if<devNum_major==0>devNum_major=dev_num; //初始化cdev結構 cdev_init<&cdev,&fops>; cdev.owner=THIS_MODULE; cdev.ops=&fops; cdev_add<&cdev,MKDEV<devNum_major,0>,1>;//注冊1個字符設備 //為設備描述結構體分配內存 devp=kmalloc<sizeof<structDevice>,GFP_KERNEL>; if<!devp> { dev_num=-ENOMEM; printk<KERN_INFO"MyDeviceDriver:FAILtogetmemory\n">; returndev_num; }<*devp>.size=DEV_SIZE;<*devp>.data=kmalloc<DEV_SIZE,GFP_KERNEL>;memset<<*devp>.data,0,<*devp>.size>;//初始化為0 return0;}voidcleanup_module<void>{ cdev_del<&cdev>;//注銷設備 kfree<devp>;//注銷設備結構體 kfree<<*devp>.data>;//注銷設備內存空間 unregister_chrdev<devNum_major,"MyDeviceDriver">;//卸載主設備號}MODULE_LICENSE<"GPL">;驅動程序測試程序#include<stdio.h>#include<stdlib.h>#include<linux/fcntl.h>#defineBUFFER_SIZE102400intmain<void>{ intdev,i=0; charc; charsource[BUFFER_SIZE];//寫入MyDeviceDriver設備的內容 chargoal[BUFFER_SIZE];//MyDeviceDriver設備的內容讀入到該goal中 printf<"inputthestringyouwanttowriteinyourdevice:\n">; while<<c=getchar<>>!='\n'> { source[i++]=c; } printf<"\n">; if<<dev=open<"/dev/MyDeviceDriver",O_RDWR>>==-1>//打開MyDeviceDriver設備失敗 printf<"FAILtoopenMyDeviceDriver!\n">; else//成功 printf<"SUCCESStoopenMyDeviceDriver!\n">; printf<"source:\n%s\n\n",source>; write<dev,source,sizeof<source>>;//把source中的內容寫入MyDeviceDriver設備 lseek<dev,0,SEEK_SET>;//把文件指針定位到文件開始的位置 read<dev,goal,sizeof<source>>;//把MyDeviceDriver設備中的內容讀入到goal中 printf<"goal:\n%s\n\n",goal>; return0;}實驗四實驗四有兩個選做題目,分別是proc文件監(jiān)控系統(tǒng)和小型文件系統(tǒng),本次實驗我選擇的題目是proc文件監(jiān)控系統(tǒng)。實驗要求了解/proc文件的特點和使用方法;監(jiān)控系統(tǒng)狀態(tài),顯示系統(tǒng)中若干部件使用狀態(tài);用圖形界面實現(xiàn)系統(tǒng)監(jiān)控狀態(tài)。具體實現(xiàn)〔1/proc文件系統(tǒng)的特點Linux的PROC文件系統(tǒng)是進程文件系統(tǒng)和內核文件系統(tǒng)的組成的復合體,是將內核數(shù)據(jù)對象化為文件形式進行存取的一種內存文件系統(tǒng),是監(jiān)控內核的一種用戶接口。它擁有一些特殊的文件〔純文本,從中可以獲取系統(tǒng)狀態(tài)信息?!?功能清單①獲取并顯示主機名,與之相關的proc文件為/proc/sys/kernel/hostname;②獲取并顯示系統(tǒng)啟動的時間,與之相關的proc文件為/proc/uptime;③顯示系統(tǒng)到目前為止持續(xù)運行的時間,與之相關的proc文件為/proc/uptime;④顯示系統(tǒng)的版本號,與之相關的proc文件為/proc/sys/kernel/ostype和/proc/sys/kernel/osrelease;顯示CPU的型號和主頻大小,與之相關的proc文件為/proc/cpuinfo;⑥通過pid或者進程名查詢一個進程,并顯示該進程的詳細信息,提供殺掉該進程的功能,與之相關的proc文件為/proc/<pid>/stat;⑦顯示系統(tǒng)所有進程的一些信息,包括pid、ppid、占用內存大小、優(yōu)先級等,與之相關的proc文件為/proc/<pid>/stat,/proc/<pid>/statm;⑧CPU使用率的圖形化顯示〔2分鐘內的歷史記錄曲線,與之相關的proc文件為/proc/stat;⑨內存和交換分區(qū)的使用率的圖形化顯示〔2分鐘內的歷史曲線,與之有關的proc文件為/proc/meminfo;⑩在狀態(tài)欄顯示當前時間,未使用到/proc中的文件;?在狀態(tài)欄顯示當前CPU使用率,與之相關的proc文件為/proc/stat;?在狀態(tài)欄顯示當前內存使用情況,與之相關的proc文件為/proc/meminfo;?用新線程運行一個其他程序,未使用到/proc中的文件;?關機功能,未使用到/proc中的文件;〔3功能實現(xiàn)①獲取并顯示主機名用fopen函數(shù)打開/proc/sys/kernel/hostname文件,然后以文件指針為輸入流,用fgets從其中讀出一行字符包含主機名,然后用格式化輸出函數(shù)sscanf函數(shù)輸出一個字符串,即主機名。②獲取并顯示系統(tǒng)啟動的時間從文件/proc/uptime中獲取系統(tǒng)啟動到現(xiàn)在的運行時間〔單位是s,然后調用time函數(shù)獲取系統(tǒng)當前時間〔單位是s,用當前時間秒數(shù)減去運行時間秒數(shù)即為系統(tǒng)啟動的時間秒數(shù),然后調用localtime函數(shù)將系統(tǒng)啟動時間秒數(shù)轉換成tm結構體類型的變量,該變量中的成員包括年份、月份、日期、星期幾、時、分、秒等,再調用輸出函數(shù)輸出即可。③顯示系統(tǒng)到目前為止持續(xù)運行的時間用fopen函數(shù)打開/proc/uptime文件,然后以文件指針為輸入流,用fgets從其中讀出一行字符包含系統(tǒng)運行時間,然后用格式化輸入函數(shù)sscanf從讀取出的字符流中輸入一個float類型的數(shù)到runtime,即系統(tǒng)運行的時間。④顯示系統(tǒng)的版本號從/proc/sys/kernel/ostype和/proc/sys/kernel/osrelease中讀取系統(tǒng)類型〔比如linux和系統(tǒng)內核版本號,處理方法和獲取系統(tǒng)運行時間的方法一樣。得到系統(tǒng)類型和系統(tǒng)內核版本號之后,調用QString類的方法arg將兩個字符串連接起來,再輸出顯示即可。=5\*GB3⑤顯示CPU的型號和主頻大小打開/proc/cpuinfo文件后發(fā)現(xiàn)CPU有四個,相同的型號,不同的主頻,后來才弄清楚所謂的四個CPU是CPU的四個核心,而"主頻"并不是主頻,而是當前時刻該核心所使用的CPU核心頻率,隨時間而變化的。弄清楚文件中的內容的含義之后,開始處理/proc/cpuinfo,從中讀取CPU的型號和頻率。處理這個文件沒有用到fopen等函數(shù),而是使用了Qt自帶的兩個類QFile和QTextStream,定義一個QFile類型的變量file,并用路徑名"/proc/cpuinfo"初始化該變量,其作用是以只讀方式打開文件/proc/cpuinfo,然后以file的地址作為參數(shù)初始化QTextStream類型的變量stream,其作用是將/proc/cpuinfo文件中的內容以字符流的形式存入變量stream中,相當于一個文本流。由于CPU的型號是一樣的,所以只讀取第一個型號名稱即可,根據(jù)CPU型號名稱所在的行,采用while循環(huán)讀取stream中的內容,每次讀取一行,當行數(shù)等于CPU型號所在行時,將讀取出的一行賦值給一個QString類型的變量,再調用QString的方法mid截取CPU型號名稱,file.close<>關閉file。CPU四個核心的主頻處理方法和CPU型號的處理方法一致,參照上述步驟即可。⑥通過pid或者進程名查詢一個進程,并顯示該進程的詳細信息,提供殺掉該進程的功能在獲取所有進程信息的時候,獲取到的所有信息已經被存儲在一個全局結構體數(shù)組變量中了,所以查詢的時候,先獲取輸入lineEdit中的文本〔QString類型,然后將文本與全局結構體數(shù)組變量的每一個數(shù)組元素的name成員和pid成員作比較,若相等,說明待查詢的進程存在,將該進程的詳細信息輸出即可。殺死進程前先要獲取將要被殺死進程的名稱或者pid,而且該進程必須存在于/proc目錄下,即先查詢一次待殺死的進程,處理方法如上所述。Linux系統(tǒng)提供了kill、pkill等殺死進程的命令,pkill通過pid殺死進程,kill通過進程名稱殺死進程。通過將lineEdit中的內容和kill或pkill組成終端命令,然后調用system函數(shù)執(zhí)行這些命令即可殺死相應的進程。=7\*GB3⑦顯示系統(tǒng)所有進程的一些信息,包括pid、ppid、占用內存大小、優(yōu)先級等系統(tǒng)的進程眾多,且進程號從1到幾萬的都有,如果從1開始遍歷訪問,效率就會很低。所以本次實驗我采用的是Linux中對目錄進行操作的函數(shù)opendir<>,readdir<>。這兩個目錄操作函數(shù)在上學期的操作系統(tǒng)第三次課程實驗中已經學習使用過,所以再次使用沒遇到多大的障礙。實現(xiàn)思路為:聲明一個DIR類型的指針dir,用opendir函數(shù)打開/proc目錄,返回值賦值給dir,然后將dir作為函數(shù)readdir的參數(shù),readdir函數(shù)返回值復制給dirent結構體指針ptr。ptr指向的結構體包含d_namechar數(shù)組成員,即文件或者目錄名,將d_name數(shù)組的0號元素分別和字符‘1’、‘9’比較,若處于這兩者之間,則表明該文件或者目錄是進程目錄,以該目錄名為參數(shù)調用獲取進程詳細信息的函數(shù)read_proc。在read_proc函數(shù)中,使用格式化輸出函數(shù)sprintf將參數(shù)目錄名c_pid對應目錄下的文件stat的路徑輸出到char數(shù)組filename中,再調用C++的類ifstream,聲明一個ifstream類性的變量meminfo,用filename初始化meminfo,然后用析取器<>>>從meminfo中輸入數(shù)據(jù)到結構體數(shù)組procInfo的每個元素的成員變量中,析取器<>>會自動忽略空字符。所需要的進程信息并不是連續(xù)存放在stat文件中的,中間包含有其他不需要顯示的進程信息,解決方法是定義一個string類型的變量temp,根據(jù)stat文件中的信息存放順序,將所有不需要的進程信息全部輸入到temp中。此外還要注意一個問題,進程名稱帶有括號"〔",所以需要將括號去掉,解決方法是使用string類的方法substr,該函數(shù)的參數(shù)有兩個,一個是想截取的字符串首字符在原字符串中的位置,第二個參數(shù)是想截取的字符串末尾字符后面一個字符,在這里就是">"。處理完畢之后,所需要的關于進程c_pid的詳細信息都存儲在全局結構體數(shù)組procInfo的元素中了。循環(huán)采用上述思路,直到所有進程目錄都被處理完畢,所有的進程信息就都存儲在了全局結構體數(shù)組procInfo中,然后用定時器觸發(fā)定時更新全局結構體數(shù)組procInfo中的內容。⑧CPU使用率的圖形化顯示由于需要畫出CPU使用率兩分鐘內的歷史記錄曲線,所以需要計算并存儲120個連續(xù)時刻的CPU利用率。定義一個全局QList變量yList,用于存放CPU使用率。在CPURate函數(shù)中調用add_point函數(shù),add_point的參數(shù)是cpuRate。在函數(shù)add_point中,首先判斷yList的大小,若大于120,則把yList的隊首元素刪除,保證yList的元素個數(shù)恒等于120;若等于0,則將yList前119個元素初始化為0,這樣的話,CPU歷史記錄曲線就會從右邊向左邊逐漸顯示出來;若大于等于1,則在yList末尾插入新的cpuRate,然后調用UpdateCPULine函數(shù)畫出記錄曲線。得到CPU使用率之后,在函數(shù)UpdateCPULine中畫圖。先在QPixmap類型的變量pix上畫曲線,pix相當于一塊畫布,然后再把pix添加到label標簽上。pix的背景色設置為藍色,然后定義一個QPainter類painter,painter的畫圖設備就是pix,定義QPen畫筆pen,畫筆顏色設置為紅色,畫筆寬度為2個像素,設置完成后,以yList中存儲的cpuRate為縱坐標,以yList的元素下標為橫坐標,并根據(jù)坐標軸單位長度所占實際像素個數(shù)稍微調整一下每個點的橫縱坐標,然后調用painter的drawLine方法畫出這些點并依次連接起來,就得到了2分鐘內的CPU使用率歷史記錄曲線,而且歷史記錄曲線可以隨著時間從右向左更新。⑨內存和交換分區(qū)的使用率的圖形化顯示由于需要畫出內存使用率兩分鐘內的歷史記錄曲線,所以需要計算并存儲120個連續(xù)時刻的內存利用率。定義一個全局QList變量yList1,用于存放內存使用率。在MemRate函數(shù)中調用add_point函數(shù),add_point的參數(shù)是memRate。在函數(shù)add_point中,首先判斷yList1的大小,若大于120,則把yList1的隊首元素刪除,保證yList1的元素個數(shù)恒等于120;若等于0,則將yList1前119個元素初始化為0,這樣的話,內存使用率歷史記錄曲線就會從右邊向左邊逐漸顯示出來;若大于等于1,則在yList1末尾插入新的memRate,然后調用UpdateMemLine函數(shù)畫出記錄曲線。得到內存使用率之后,在函數(shù)UpdateMemLine中畫圖。先在QPixmap類型的變量pix上畫曲線,pix相當于一塊畫布,然后再把pix添加到label標簽上。pix的背景色設置為藍色,然后定義一個QPainter類painter,painter的畫圖設備就是pix,定義QPen畫筆pen,畫筆顏色設置為紅色,畫筆寬度為2個像素,設置完成后,以yList1中存儲的memRate為縱坐標,以yList1的元素下標為橫坐標,并根據(jù)坐標軸單位長度所占實際像素個數(shù)稍微調整一下每個點的橫縱坐標,然后調用painter的drawLine方法畫出這些點并依次連接起來,就得到了2分鐘內的內存使用率歷史記錄曲線,而且歷史記錄曲線可以隨著時間從右向左更新。⑩在狀態(tài)欄顯示當前時間調用QDateTime的方法currentDateTime獲取當前時間time,time是一個QDateTime類型的變量,然后調用QDateTime的方法toString把time轉化成格式為yyyy-MM-ddhh:mm:ssdddd的QString字符串,再在主窗口的狀態(tài)欄顯示輸出即可。?在狀態(tài)欄顯示當前CPU使用率CPU的使用率是指CPU的使用時間和CPU總時間的比值。因為/proc/stat文件中的所有值都是從系統(tǒng)啟動開始累計到當前時刻,所以計算CPU使用率時需要取兩個采樣點,利用兩個點的差值計算CPU使用率,此次實驗采樣方法是每隔1秒采樣一次。CPU使用率的計算公式為cpuRate=100.0-<idle2-idle1>*100.0/<total2-total1>。定義一個全局結構體CPU_USE,具體定義如下:typedefstructCPU_USE{charname[16];//cpuunsignedintuser;unsignedintnice;unsignedintsystem;unsignedintidle;unsignedintiowait;unsignedintirq;unsignedintsoftirq;}cpu_use;CPU總時間的值等于結構體CPU_USE中7個unsignedint類型的成員值之和。計算之前,調用get_cpu_use_stat函數(shù)獲取一個CPU狀態(tài),sleep一秒后再調用該函數(shù)獲取第二個CPU狀態(tài),然后用上述CPU使用率計算公式計算即可。?在狀態(tài)欄顯示當前內存使用情況內存使用率是指已使用的內存和總內存的比值。內存使用率的計算公式為:memRate=<total–<free+buffers+cached>>*100.0/total。定義一個全局結構體MEM_USE,具體定義如下:typedefstructMEM_USE{unsignedlongtotal;unsignedlongfree;unsignedlongbuffers;unsignedlongcached;}mem_use;該結構體中的成員的值都來自文件/proc/meminfo,聲明一個ifstream類性的變量meminfo,用/proc/meminfo初始化meminfo,然后用析取器<>>>從meminfo中輸入數(shù)據(jù)到結構體mem_use的成員變量中,析取器<>>會自動忽略空字符。所需要的內存數(shù)據(jù)信息并不是連續(xù)存放在/proc/meminfo文件中的,中間包含有其他不需要的內存數(shù)據(jù)信息,解決方法是定義一個string類型的變量str,根據(jù)/proc/meminfo文件中的信息存放順序,將所有不需要的內存數(shù)據(jù)信息全部輸入到str中。得到內存使用的數(shù)據(jù)信息之后,使用上述內存使用率計算公式計算即可。?用新線程運行一個其他程序在主窗口中添加一個lineEdit控件,獲取該控件中輸入的程序名稱,然后調用QProcess類的start方法運行該程序。?關機功能由于關機功能需要輸入密碼獲取root權限,所以需要想方法在點擊關機按鈕后輸入密碼。定義一個QString類型的變量passWord,調用類QInputDialog的方法getText,會彈出一個對話框提示輸入密碼,該方法的返回值即為密碼,將返回值賦值給passWord變量;當對話框的OK按鈕被點擊時,用QString<"echo%1|sudo-Sshutdown-hnow">.arg<passWord>初始化QString類型的變量sudo,再把sudo轉換成char*類型,然后調用system函數(shù)執(zhí)行關機命令。〔4界面設計新建一個QtWidgetsApplication工程,用setWindowTitle函數(shù)將主窗口的標題改為"proc進程管理器",設置窗口的初始大小為〔650,500,初始位置為顯示屏左上角,即坐標原點。在主窗口底部添加一個狀態(tài)欄控件,用QStatusBar實現(xiàn)。狀態(tài)欄中添加三個標簽和一個按鈕,三個標簽分別用于顯示當前時間、CPU使用率、內存使用率,這三個信息的顯示函數(shù)都與定時器QTimer綁定,隨時間自動更新,按鈕用于觸發(fā)關機函數(shù)。在主窗口的窗體中添加tabWidget控件,設置四個tab選項卡tab_1、tab_2、tab_3、tab_4。tab_1選項卡用于顯示主機名、系統(tǒng)啟動時間、系統(tǒng)運行時間、系統(tǒng)版本號、CPU型號和主頻等信息,這些內容全部用QLabel類的標簽顯示,其中系統(tǒng)運行時間和CPU主頻函數(shù)是槽函數(shù),都和定時器QTimer綁定,隨著時間自動更新。tab_2選項卡用于顯示進程詳細信息,進程詳細信息包括進程名、pid、ppid、內存占用和優(yōu)先級,這些信息用tableWidget控件顯示,tableWidget控件設置為禁止選中、禁止修改,tableWidget的列數(shù)是固定的5列,行數(shù)動態(tài)確定,由獲取所有進程詳細信息的函數(shù)get_pid_info的返回值提供;這樣做的好處是,當創(chuàng)建新進程或者殺死進程時,tableWidget不會出現(xiàn)行數(shù)不夠或者有空行的情況,并且ProcessInfo函數(shù)〔即控制顯示進程信息的函數(shù)與QTimer綁定,隨時間定時更新。tab_3選項卡用于提供查詢進程、殺死進程、創(chuàng)建新進程的操作面板,查詢進程的輸入框用lineEdit控件實現(xiàn),該控件的好處是可以直接調用控件所包含的方法text獲取輸入框的內容,便于查詢進程信息;在lineEdit下方放置的是tableWidget控件,同樣,該控件禁止選中、禁止修改,用于顯示查詢的進程詳細信息;tableWidget控件下方是關閉進程的按鈕,當點擊該按鈕時便會觸發(fā)killProcess函數(shù)關閉進程;創(chuàng)建進程的進程名輸入框同樣也是用lineEdit控件實現(xiàn),當點擊"運行"按鈕時便會觸發(fā)CreateProcess函數(shù)。tab_4選項卡用于顯示CPU使用率歷史記錄曲線和內存使用率歷史記錄曲線。〔5程序運行結果源代碼#mainwindow.h,包含各種槽函數(shù)#ifndefMAINWINDOW_H#defineMAINWINDOW_H#include<QMainWindow>#include<QLabel>#include<QPushButton>classQTabWidget;namespaceUi{classMainWindow;}classMainWindow:publicQMainWindow{Q_OBJECTpublic:explicitMainWindow<QWidget*parent=0>;~MainWindow<>;private:Ui::MainWindow*ui;private:QPushButton*shutButton;QLabel*NowTimeLabel;QLabel*CPUUseLabel;QLabel*MemUseLabel;QTabWidget*tabwidget;QList<float>yList;QList<float>yList1;voidinit_StatusBar<>;voidHostName<>;voidBootTime<>;voidOSType<>;voidadd_point<floatcpuRate>;voidUpdateCPULine<>;voidadd_point_mem<floatmemRate>;voidUpdateMemLine<>;privateslots:voidNowTime<>;voidCPURate<>;voidMemRate<>;voidrun_time<>;voidCPUInfo<>;voidProcessInfo<>;voidQueryProcess<>;voidPasswordToShutdown<>;voidKillProcess<>;voidCreateProcess<>;};#endif//MAINWINDOW_H#sys.h,獲取主機名、系統(tǒng)運行時間、系統(tǒng)版本號#ifndefSYS#defineSYS#include<stdio.h>#include<stdlib.h>#include<string>#include<QString>char*get_hostname<>{FILE*fp;charhost[8];char*hostname;hostname=<char*>malloc<7*sizeof<char>>;fp=fopen<"/proc/sys/kernel/hostname","r">;fgets<host,sizeof<host>,fp>;sscanf<host,"%s",hostname>;fclose<fp>;returnhostname;}floatget_run_time_sec<>{FILE*fp;floatrunTime;chartime[32];fp=fopen<"/proc/uptime","r">;fgets<time,sizeof<time>,fp>;sscanf<time,"%f",&runTime>;fclose<fp>;returnrunTime;}QStringget_os_type<>{QStringos;charostype[6],osrelease[8];charbuff1[16],buff2[16];FILE*fp1,*fp2;fp1=fopen<"/proc/sys/kernel/ostype","r">;fp2=fopen<"/proc/sys/kernel/osrelease","r">;fgets<buff1,sizeof<buff1>,fp1>;fgets<buff2,sizeof<buff2>,fp2>;sscanf<buff1,"%s",ostype>;sscanf<buff2,"%s",osrelease>;os=QString<"%1%2">.arg<ostype>.arg<osrelease>;fclose<fp1>;fclose<fp2>;returnos;}#endif//SYS#process.h,獲取所有進程詳細信息#ifndefPROCESS#definePROCESS#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<dirent.h>#include<fstream>#include<iostream>#include<string>usingnamespacestd;structPROC_INFO{stringname;stringpid;stringppid;stringrss;stringpriority;}procInfo[40960];voidread_proc<PROC_INFO*pidinfo,constchar*c_pid>{stringtemp,pidname;charfilename[18];sprintf<filename,"/proc/%s/stat",c_pid>;std::ifstreammeminfo<filename>;meminfo>><pidinfo->pid>>>pidname>>temp>><pidinfo->ppid>>>temp>>temp;meminfo>>temp>>temp>>temp>>temp>>temp>>temp;meminfo>>temp>>temp>>temp>>temp>>temp>><pidinfo->priority>;meminfo>>temp>>temp>>temp>>temp>>temp>><pidinfo->rss>;pidinfo->name=pidname.substr<1,pidname.find<'>'>-1>;//remove"<>"meminfo.close<>;}intget_pid_info<>{DIR*dir;structdirent*ptr;inti=0;if<!<dir=opendir<"/proc">>>return0;while<<ptr=readdir<dir>>!=false>{if<ptr->d_name[0]>='1'&&ptr->d_name[0]<='9'>{read_proc<&<procInfo[i]>,ptr->d_name>;i++;}}closedir<dir>;returni;}#endif//PROCESS#mem.h,計算內存使用率#ifndefMEM#defineMEM#include<stdio.h>#include<stdlib.h>#include<fstream>#include<iostream>#include<string>usingnamespacestd;typedefstructMEM_USE{unsignedlongtotal;unsignedlongfree;unsignedlongbuffers;unsignedlongcached;}mem_use;voidget_mem_use_stat<mem_use*memStat>{stringstr;unsignedlongmemtotal,memfree,memavailable,membuffers,memcached;std::ifstreammeminfo<"/proc/meminfo">;meminfo>>str>>memtotal>>str;meminfo>>str>>memfree>>str;meminfo>>str>>memavailable>>str;meminfo>>str>>membuffers>>str;meminfo>>str>>memcached>>str;<*memStat>.total=memtotal;<*memStat>.free=memfree;<*memStat>.buffers=membuffers;<*memStat>.cached=memcached;meminfo.close<>;}floatclacu_memRate<mem_use*memStat>{floatmemRate=0.0;memRate=<float><<<*memStat>.total-<<*memStat>.free+<*memStat>.buffers+<*memStat>.cached>>*100.0/<*memStat>.total>;returnmemRate;}#endif//MEM#cpu.h,計算CPU使用率、獲取CPU型號和主頻#ifndefCPU#defineCPU#include<stdio.h>#include<stdlib.h>#include<QString>#include<QFile>#include<QTextStream>typedefstructCPU_USE{charname[16];unsignedintuser;unsignedintnice;unsignedintsystem;unsignedintidle;unsignedintiowait;unsignedintirq;unsignedintsoftirq;}cpu_use;voidget_cpu_use_stat<cpu_use*cpuStat>{FILE*f;charcpu[256];f=fopen<"/proc/stat","r">;fgets<cpu,sizeof<cpu>,f>;sscanf<cpu,"%s%u%u%u%u%u%u%u",cpuStat->name,&cpuStat->user,&cpuStat->nice,&cpuStat->system,&cpuStat->idle,&cpuStat->iowait,&cpuStat->irq,&cpuStat->softirq>;fclose<f>;}floatcalcu_cpu_rate<cpu_use*cpuStat1,cpu_use*cpuStat2>{unsignedlongtotal1,total2;floatcpuIdle=0.0;floatcpuRate=0.0;total1=<unsignedlong><cpuStat1->user+cpuStat1->nice+cpuStat1->system+cpuStat1->idle+cpuStat1->iowait+cpuStat1->irq+cpuStat1->softirq>;total2=<unsignedlong><cpuStat2->user+cpuStat2->nice+cpuStat2->system+cpuStat2->idle+cpuStat2->iowait+cpuStat2->irq+cpuStat2->softirq>;if<total1!=total2>{cpuIdle=<float><<cpuStat2->idle-cpuStat1->idle>*100.0/<total2-total1>>;cpuRate=100.0-cpuIdle;}elsecpuRate=0.0;returncpuRate;}//getcpuinformationQStringget_processor<>{inti=0;QStringprocessor;QStringstr;QFilefile<"/proc/cpuinfo">;file.open<QIODevice::ReadOnly|QIODevice::Text>;QTextStreamstream<&file>;stream.readLine<>;while<!stream.atEnd<>>{str=stream.readLine<>;if<i==3>{processor=str;break;}i++;}processor=processor.mid<13,56>;file.close<>;returnprocessor;}QStringget_Hz0<>{inti=0;QStringHz0;QStringstr;QFilefile<"/proc/cpuinfo">;file.open<QIODevice::ReadOnly|QIODevice::Text>;QTextStreamstream<&file>;stream.readLine<>;while<!stream.atEnd<>>{str=stream.readLine<>;if<i==6>{Hz0=str;break;}i++;}Hz0=Hz0.mid<11,18>;file.close<>;returnHz0;}QStringget_Hz1<>{inti=0;QStringHz1;QStringstr;QFilefile<"/proc/cpuinfo">;file.open<QIODevice::ReadOnly|QIODevice::Text>;QTextStreamstream<&file>;stream.readLine<>;while<!stream.atEnd<>>{str=stream.readLine<>;if<i==33>{Hz1=str;break;}i++;}Hz1=Hz1.mid<11,18>;file.close<>;returnHz1;}QStringget_Hz2<>{inti=0;QStringHz2;QStringstr;QFilefile<"/proc/cpuinfo">;file.open<QIODevice::ReadOnly|QIODevice::Text>;QTextStreamstream<&file>;stream.readLine<>;while<!stream.atEnd<>>{str=stream.readLine<>;if<i==60>{Hz2=str;break;}i++;}Hz2=Hz2.mid<11,18>;file.close<>;returnHz2;}QStringget_Hz3<>{inti=0;QStringHz3;QStringstr;QFilefile<"/proc/cpuinfo">;file.open<QIODevice::ReadOnly|QIODevice::Text>;QTextStreamstream<&file>;stream.readLine<>;while<!stream.atEnd<>>{str=stream.readLine<>;if<i==87>{Hz3=str;break;}i++;}Hz3=Hz3.mid<11,18>;file.close<>;returnHz3;}#endif//CPU#mainwindow.cpp,所有功能的實現(xiàn)函數(shù)#include"mainwindow.h"#include"ui_mainwindow.h"#include<QtCore>#include<time.h>#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<QStringList>#include<QMessageBox>#include<QInputDialog>#include<QTableWidget>#include<QTableWidgetItem>#include<QProcess>#include<QPainter>#include"cpu.h"#include"mem.h"#include"sys.h"#include"process.h"MainWindow::MainWindow<QWidget*parent>:QMainWindow<parent>,ui<newUi::MainWindow>{ui->setupUi<this>;setWindowTitle<"proc進程管理器">;move<0,0>;resize<650,500>;init_StatusBar<>;HostName<>;BootTime<>;OSType<>;QTimer*timer=newQTimer<this>;connect<timer,SIGNAL<timeout<>>,this,SLOT<NowTime<>>>;connect<timer,SIGNAL<timeout<>>,this,SLOT<CPURate<>>>;connect<timer,SIGNAL<timeout<>>,this,SLOT<MemRate<>>>;connect<timer,SIGNAL<timeout<>>,this,SLOT<run_time<>>>;connect<timer,SIGNAL<timeout<>>,this,SLOT<CPUInfo<>>>;connect<shutButton,SIGNAL<clicked<>>,this,SLOT<PasswordToShutdown<>>>;connect<ui->queryButton,SIGNAL<clicked<>>,this,SLOT<QueryProcess<>>>;connect<ui->killButton,SIGNAL<clicked<>>,this,SLOT<KillProcess<>>>;connect<ui->runButton,SIGNAL<clicked<>>,this,SLOT<CreateProcess<>>>;timer->start<1>;QTimer*timer1=newQTimer<this>;connect<timer1,SIGNAL<timeout<>>,this,SLOT<ProcessInfo<>>>;timer1->start<2000>;}MainWindow::~MainWindow<>{deleteui;}voidMainWindow::init_StatusBar<>{QStatusBar*StatBar=ui->statusBar;NowTimeLabel=newQLabel;NowTimeLabel->setMinimumSize<200,30>;NowTimeLabel->setFrameShape<QFrame::WinPanel>;NowTimeLabel->setFrameShadow<QFrame::Sunken>;CPUUseLabel=newQLabel;CPUUseLabel->setMinimumSize<200,30>;CPUUseLabel->setFrameShape<QFrame::WinPanel>;CPUUseLabel->setFrameShadow<QFrame::Sunken>;MemUseLabel=newQLabel;MemUseLabel->setMinimumSize<200,30>;MemUseLabel->setFrameShape<QFrame::WinPanel>;MemUseLabel->setFrameShadow<QFrame::Sunken>;shutButton=newQPushButton;shutButton->setMinimumSize<60,30>;shutButton->setText<"off">;StatBar->addWidget<NowTimeLabel>;StatBar->addWidget<CPUUseLabel>;StatBar->addWidget<MemUseLabel>;StatBar->addWidget<shutButton>;}voidMainWindow::NowTime<>{QDateTimetime=QDateTime::currentDateTime<>;QStringnowTime=time.toString<"yyyy-MM-ddhh:mm:ssdddd">;NowTimeLabel->setText<nowTime>;NowTimeLabel->setAlignment<Qt::AlignCenter>;}voidMainWindow::CPURate<>{cpu_usecpuStat1,cpuStat2;floatcpuRate;QStringstr;get_cpu_use_stat<&cpuStat1>;sleep<1>;get_cpu_use_stat<&cpuStat2>;cpuRate=calcu_cpu_rate<&cpuStat1,&cpuStat2>;cpuRate=<<int><cpuRate*100+0.5>>/100.0;str=QString<"CPU使用率:%1%2">.arg<cpuRate>.arg<"%">;CPUUseLabel->setText<str>;CPUUseLabel->setAlignment<Qt::AlignCenter>;add_point<cpuRate>;}voidMainWindow::MemRate<>{mem_useMemUse;QStringstr;floatmemRate;get_mem_use_stat<&MemUse>;memRate=clacu_memRate<&MemUse>;memRate=<<int><memRate*100+0.5>>/100.0;str=QString<"內存使用率:%1%2">.arg<memRate>.arg<"%">;MemUseLabel->setText<str>;MemUseLabel->setAlignment<Qt::AlignCenter>;add_point_mem<memRate>;}voidMainWindow::HostName<>{char*str;QStringhostname;str=<char*>malloc<7*sizeof<char>>;str=get_hostname<>;hostname=QString<str>;ui->hostlabel->setText<hostname>;}voidMainWindow::run_time<>{floatrunTime;runTime=get_run_time_sec<>;QStringrun=QString<"%1%2">.arg<runTime>.arg<"秒">;ui->runtimelabel->setText<run>;}voidMainWindow::BootTime<>{QStringboot;time_tcur_time=0;time_tboot_time=0;structtm*ptm=NULL;time_truntime;QStringweek[7]={"星期天","星期一","星期二","星期三","星期四","星期五","星期六"};runtime=<time_t><get_run_time_sec<>>;time<&cur_time>;boot_time=cur_time-runtime;ptm=localtime<&boot_time>;boot=QString<"%1-%2-%3%4:%5:%6%7">.arg<ptm->tm_year+1900>.arg<ptm->tm_mon+1>.arg<ptm->tm_mday>.arg<ptm->tm_hour>.arg<ptm->tm_min>.arg<ptm->tm_sec>.arg<week[ptm->tm_wday]>;ui->bootlabel->setText<boot>;}voidMainWindow::OSType<>{QStringos;os=get_os_type<>;ui->ostypelabel->setText<os>;}voidMainWindow::PasswordToShutdown<>{QStringpassWord;QStringsudo;char*command;boolOK;QByteArrayba;passWord=QInputDialog::getText<this,"輸入密碼","輸入密碼",QLineEdit::Normal,"",&OK>;if<OK>{sudo=QString<"echo%1|sudo-Sshutdown-hnow">.arg<passWord>;ba=sudo.toLatin1<>;command=ba.data<>;system<command>;}}voidMainWindow::CPUInfo<>{QStringprocessor;QStringHz0,Hz1,Hz2,Hz3;processor=get_processor<>;ui->processorlabel0->setText<QString<"0:%1">.arg<processor>>;ui->processorlabel1->setText<QString<"1:%1">.arg<processor>>;ui->processorlabel2->setText<QString<"2:%1">.arg<processor>>;ui->processorlabel3->setText<QString<"3:%1">.arg<processor>>;Hz0=get_Hz0<>;Hz0=QString<"%1%2">.arg<Hz0>.arg<"MHz">;ui->Hzlabel0->setText<Hz0>;Hz1=get_Hz1<>;Hz1=QString<"%1%2">.arg<Hz1>.arg<"MHz">;ui->Hzlabel1->setText<Hz1>;Hz2=get_Hz2<>;Hz2=QString<"%1%2">.arg<Hz2>.arg<"MHz">;ui->Hzlabel2->setText<Hz2>;Hz3=get_Hz3<>;Hz3=QString<"%1%2">.arg<Hz3>.arg<"MHz">;ui->Hzlabel3->setText<Hz3>;}voidMainWindow::ProcessInfo<>{intpidNum;inti;QStringListheaders;QTableWidgetItem*nameItem;QTableWidgetItem*pidItem;QTableWidgetItem*ppidItem;QTableWidgetItem*rssItem;QTableWidgetItem*priorityItem;pidNum=get_pid_info<>;ui->tableWidget->setColumnCount<5>;ui->tableWidget->setRowCount<pidNum>;headers<<"進程名"<<"pid"<<"ppid"<<"內存占用/KB"<<"優(yōu)先級";ui->tableWidget->setHorizontalHeaderLabels<headers>;for<i=0;i<pidNum;i++>{nameItem=newQTableWidgetItem<QString::fromStdString<procInfo[i].name>>;ui->tableWidget->setItem<i,0,nameItem>;nameItem->setTextAlignment<Qt::AlignCenter>;pidItem=newQTableWidgetItem<QString::fromStdString<procInfo[i].pid>>;ui->tableWidget->setItem<i,1,pidItem>;pidItem->setTextAlignment<Qt::AlignCenter>;ppidItem=newQTableWidgetItem<QString::fromStdString<procInfo[i].ppid>>;ui->tableWidget->setItem<i,2,ppidItem>;ppidItem->setTextAlignment<Qt::AlignCenter>;rssItem=newQTableWidgetItem<QString::fromStdString<procInfo[i].rss>>;ui->tableWidget->setItem<i,3,rssItem>;rssItem->setTextAlignment<Qt::AlignCenter>;priorityItem=newQTableWidgetItem<QString::fromStdString<procInfo[i].priority>>;ui->tableWidget->setItem<i,4,priorityItem>;priorityItem->setTextAlignment<Qt::AlignCenter>;}ui->tableWidget->setColumnWidth<0,121>;ui->tableWidget->setColumnWidth<1,121>;ui->tableWidget->setColumnWidth<2,121>;ui->tableWidget->setColumnWidth<3,121>;ui->tableWidget->setColumnWidth<4,121>;ui->tableWidget->setEditTriggers<QAbstractItemView::NoEditTriggers>;ui->tableWidget->setSelectionMode<QAbstractItemView::NoSelection>;}voidMainWindow::QueryProcess<>{QStringqueryitem;intpidNum,i;QStringListheaders;QTableWidgetItem*nameItem;QTableWidgetItem*pidItem;QTableWidgetItem*ppidItem;QTableWidgetItem*rssItem;QTableWidgetItem*priorityItem;QHeaderView*headerView=ui->tableWidget_2->verticalHeader<>;headerView->setHidden<true>;//norownumberqueryitem=ui->lineEdit->text<>;pidNum=get_pid_info<>;for<i=0;i<pidNum;i++>{if<queryitem==QString::fromStdString<procInfo[i].name>||queryitem==QString::fromStdString<procInfo[i].pid>>break;}ui->tableWidget_2->setColumnCount<5>;ui->tableWidget_2->setRowCount<1>;headers<<"進程名"<<"pid"<<"ppid"<<"內存占用/KB"<<"優(yōu)先級";ui->tableWidget_2->setHorizontalHeaderLabels<headers>;nameItem=newQTableWidgetItem<QString::fromStdString<procInfo[i].name>>;ui->tableWidget_2->setItem<0,0,nameItem>;nameItem->setTextAlignment<Qt::AlignCenter>;pidItem=newQTableWidgetItem<QString::fromStdString<procInfo[i].pid>>;ui->tableWidget_2->setItem<0,1,pidItem>;pidItem->setTextAlignment<Qt::AlignCenter>;ppidItem=newQTableWidgetItem<QString::fromStdString<procInfo[i].ppid>>;ui->tableWidget_2->setItem<0,2,ppidItem>;ppidItem->setTextAlignment<Qt::AlignCenter>;rssItem=newQTableWidgetItem<QString::fromStdString<procInfo[i].rss>>;ui->tableWidg
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 婚介公司合同(2025年度)-婚戀品牌推廣與營銷協(xié)議
- 2025股東股權協(xié)議:智慧城市建設與運營
- 二零二五年度蔬菜大棚租賃權及經營權整體轉讓合同
- 二零二五醫(yī)療事故賠償協(xié)議書范本編寫指南
- 二零二五年度餐飲行業(yè)員工績效考核聘用合同
- 2025年度桶裝水電商平臺用戶數(shù)據(jù)分析與精準營銷合同
- 二零二五年度車庫租賃與智能停車系統(tǒng)合作協(xié)議
- 2025年度珠寶店員工勞動合同終止及后續(xù)服務合同
- 二零二五年度建筑工程安全生產監(jiān)督檢查合同
- 動產拍賣委托代理協(xié)議書(2025年度藝術品拍賣合作)
- 2024年07月山東省泰山財產保險股份有限公司2024年夏季校園招考29名工作人員筆試歷年參考題庫附帶答案詳解
- 臨床護理死亡病例討論
- 2025年廣東韶關城投集團招聘筆試參考題庫含答案解析
- 醫(yī)療器械生產企業(yè)并購合同
- 2025版新能源汽車充電站建設合同含政府補貼及稅收優(yōu)惠條款
- 2025年北京國資公司招聘筆試參考題庫含答案解析
- 建設工程總承包EPC建設工程項目管理方案1
- iso28000-2022供應鏈安全管理手冊程序文件表單一整套
- 養(yǎng)老院敬老院福利醫(yī)養(yǎng)機構消防知識培訓科普講座教學課件
- 子癇診斷及治療
- 2024年度酒店智能化系統(tǒng)安裝工程合同
評論
0/150
提交評論