#include <QDebug>
#include <QDir>
#include <QStandardItem>
#include <QDateTime>
#include <fstream>
#include <string>
#include <cstring>

void MainWindow::get_process_info(int total_diff)
{
    struct dirent *ptr;
    DIR *dir;
    std::ifstream input;
    dir = opendir('/proc');
    int i = 0;
    int total_threads = 0;
    int cnt = 0;
    while((ptr = readdir(dir)) != NULL) {
        if (is_digit(ptr->d_name)) {
            // qDebug() << ptr->d_name << endl;
            model->setItem(i, 5, new QStandardItem(ptr->d_name));
            model->item(i, 5)->setTextAlignment(Qt::AlignCenter);
            char filename[20] = '/proc/';
            strcat(filename, ptr->d_name);
            input.open(strcat(filename, '/stat'));
            if (input.is_open()) {
                cnt++;
                std::string name;   // process name
                int pid;            // process id
                char state;         // process state : 'RSDZTW'
                int ppid, pgid, sid, tty_nr, tty_pgrp, flags, min_flt;
                int cmin_flt, maj_flt, cmaj_flt, priority, nice;
                long utime, stime, cutime, cstime;
                int num_threads, zero;
                unsigned long long start_time;
                input >> pid >> name >> state >> ppid >> pgid >> sid >> tty_nr \
                        >> tty_pgrp >> flags >> min_flt >> cmin_flt >> maj_flt \
                        >> cmaj_flt >> utime >> stime >> cutime >> cstime >> priority \
                        >> nice >> num_threads >> zero >> start_time;
                // discard the parentheses
                char* tmp = (char*)name.c_str();
                int len = strlen(tmp);
                tmp[len - 1] = '\0';
                model->setItem(i, 0, new QStandardItem(tmp+1));
                // num threads
                if (this->state == CPU) {
                    model->setItem(i, 3, new QStandardItem(QString::number(num_threads)));
                    model->item(i, 3)->setTextAlignment(Qt::AlignCenter);
                } else {
                    model->setItem(i, 4, new QStandardItem(QString::number(num_threads)));
                    model->item(i, 4)->setTextAlignment(Qt::AlignCenter);
                }
                total_threads += num_threads;
                if (this->state == CPU) {
                    // display process state
                    switch (state) {
                    case 'R':
                        model->setItem(i, 4, new QStandardItem('运行'));
                        break;
                    case 'S':
                        model->setItem(i, 4, new QStandardItem('休眠'));
                        break;
                    case 'D':
                        model->setItem(i, 4, new QStandardItem('TASK_UNINTERRUPTIBLE'));
                        break;
                    case 'T':
                        model->setItem(i, 4, new QStandardItem('停止'));
                        break;
                    case 'Z':
                        model->setItem(i, 4, new QStandardItem('Zombie'));
                        break;
                    case 'W':
                        model->setItem(i, 4, new QStandardItem('Paging'));
                        break;
                    default:
                        break;
                    }
                    model->item(i, 4)->setTextAlignment(Qt::AlignCenter);

                    // compute processes' CPU rate
                    if (total_diff == 0) {
                        model->setItem(i, 1, new QStandardItem('00.00%'));
                    } else {
                        int total_process = utime + stime + cutime + cstime;
                        if (process_map->find(pid) != process_map->end()) {
                            int total_pro_diff = total_process - (*process_map)[pid];
                            float rate = total_pro_diff * 8.0 / total_diff;
                            QString temp = tr('%1%').arg(QString::number(rate * 100, 'f', 2));
                            if (temp.length() < 6) {
                                temp = tr('0%1').arg(temp);
                            }
                            model->setItem(i, 1, new QStandardItem(temp));

                        } else {
                            model->setItem(i, 1, new QStandardItem('00.00%'));
                        }
                        (*process_map)[pid] = total_process;
                    }
                    model->item(i, 1)->setTextAlignment(Qt::AlignCenter);
                    // process runing time
                    std::ifstream uptime;
                    uptime.open('/proc/uptime');
                    if (uptime.is_open()) {
                        float total_time;
                        uptime >> total_time;
                        start_time = (int)(total_time - start_time * 1.0 / CLK_TCK);
                        // qDebug() << pid << '\t' << start_time << endl;
                        QDateTime time = QDateTime::fromTime_t(start_time, Qt::UTC, -8 * 60 * 60);
                        QString s_time = time.toString('hh:mm:ss');
                        model->setItem(i, 2, new QStandardItem(s_time));
                        uptime.close();
                        model->item(i, 2)->setTextAlignment(Qt::AlignCenter);
                    }
                }
                input.close();
                // username
                char filename2[20] = '/proc/';
                strcat(filename2, ptr->d_name);
                std::ifstream input2;
                input2.open(strcat(filename2, '/status'));
                if (input2.is_open()) {
                    int j = 0;
                    char buffer[100];
                    while (j < 7) {
                        j++;
                        input2.getline(buffer, 100);
                    }
                    std::string s_uid;
                    int uid;
                    input2 >> s_uid >> uid;
                    if (username_dict->find(uid) != username_dict->end()) {
                        std::string user = (*username_dict)[uid];
                        //qDebug() << pid << '\t' << user.c_str();
                        model->setItem(i, 6, new QStandardItem(user.c_str()));
                    }
                    else {
                        model->setItem(i, 6, new QStandardItem('nobody'));
                    }
                    model->item(i, 6)->setTextAlignment(Qt::AlignLeft);
                    if (this->state == MEM) {
                        j = 0;
                        while (j < 9) {
                            j++;
                            input2.getline(buffer, 100);
                        }
                        std::string tmp;
                        int vmsize, vmrss;
                        input2 >> tmp >> vmsize;
                        input2.getline(buffer, 100);
                        input2.getline(buffer, 100);
                        input2.getline(buffer, 100);
                        input2.getline(buffer, 100);
                        input2 >> tmp >> vmrss;
                        float rate = vmrss * 100.0 / this->mem_size;
                        QString temp = tr('%1%').arg(QString::number(rate, 'f', 2));
                        if (temp.length() < 6) {
                            temp = tr('0%1').arg(temp);
                        }
                        model->setItem(i, 1, new QStandardItem(temp));
                        model->setItem(i, 2, new QStandardItem(get_proper_unit(vmsize).c_str()));
                        model->setItem(i, 3, new QStandardItem(get_proper_unit(vmrss).c_str()));
                        model->item(i, 1)->setTextAlignment(Qt::AlignCenter);
                        //model->sort(1, Qt::DescendingOrder);
                    }
                    input2.close();
                } else {
                    qDebug() << tr('Cannot open status: %1!').arg(ptr->d_name) << endl;
                }
            } else {
                qDebug() << tr('Cannot open %1!').arg(ptr->d_name) << endl;
                i--;
            }
            i++;
        }
    }
    if (this->state == CPU) {
        ui->right_2->setText(tr('进程\t            %1').arg(i));
        ui->right_3->setText(tr('线程\t            %1').arg(total_threads));
    }
    model->sort(1, Qt::DescendingOrder);
    // qDebug() << 'now: ' << cnt << 'last:' << this->num_processes << 'rows:' << model->rowCount();
    if (cnt < this->num_processes) {
        int diff= this->num_processes - cnt;
        model->removeRows(model->rowCount() - diff, diff);
    }
    this->num_processes = cnt;
}

代码功能:

这段代码实现了在 Qt 应用程序中获取和显示系统进程信息的功能。它通过读取 /proc 虚拟文件系统中的文件来获取进程的 CPU 使用率、内存使用率、状态、运行时间、用户名等信息,并将其显示在一个表格视图中。

代码解释:

  1. 获取进程列表: 代码首先打开 /proc 目录,并遍历其中的所有条目。对于每个条目,它会检查其名称是否为数字(表示进程 ID),如果是,则将其视为一个进程。

  2. 读取进程信息: 对于每个进程,代码会打开 /proc/[pid]/stat/proc/[pid]/status 文件来读取进程的详细信息,例如进程名称、状态、CPU 使用时间、内存使用量等。

  3. 计算 CPU 使用率: 代码使用两次读取 /proc/[pid]/stat 文件的结果,计算出进程在两次读取之间的时间间隔内的 CPU 使用率。

  4. 获取用户名: 代码读取 /proc/[pid]/status 文件中的用户 ID,并将其转换为相应的用户名。

  5. 显示进程信息: 代码将获取到的进程信息存储在一个 QStandardItemModel 对象中,并将其显示在一个表格视图中。

代码亮点:

  • 使用 Qt 框架提供的类和函数来简化代码编写。
  • 使用 /proc 虚拟文件系统来获取进程信息,避免了使用系统调用。
  • 计算并显示了进程的 CPU 使用率、内存使用率、状态、运行时间、用户名等详细信息。
  • 使用表格视图来显示进程信息,方便用户查看和管理进程。

注意事项:

  • 这段代码需要在 Linux 系统上运行。
  • 代码中使用了一些 Qt 框架特有的类和函数,需要对 Qt 框架有一定的了解才能理解。
  • 代码中没有进行错误处理,实际应用中需要添加相应的错误处理代码。
C++ Qt 获取和显示进程信息

原文地址: https://www.cveoy.top/t/topic/AJD 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录