0
点赞
收藏
分享

微信扫一扫

html+css 实现水波纹按钮

文章目录

0. 引言

Linux系统提供了/proc文件系统,通过这个文件系统,用户可以获取当前运行的进程的详细信息,包括CPU和内存使用情况。每个进程都有一个独立的目录,命名为其进程ID(PID),而在这些目录中有多个文件存储着进程的状态信息。

本文将介绍如何在Linux系统上编写一个简单的C++程序,来获取指定进程(例如进程名称为sshd)的CPU和内存使用情况。

1. 进程信息获取

在获取进程信息时,我们主要关注以下几个文件:

  • /proc/[PID]/stat:该文件包含进程的状态信息,包括CPU时间。
  • /proc/[PID]/status:该文件包含进程的内存使用情况。
  • /proc/[PID]/comm:该文件包含进程的名称。

2. 实现

2.1 代码

#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <memory>
#include <array>

struct sysinfo {
  std::string os;
  std::string cpu;
  std::string ram;
};

struct process_info {
  int pid;
  std::string name;
  double cpu_usage;
  std::string mem_usage;
};

std::string exec_command(const char* cmd) {
  std::array<char, 128> buffer;
  std::string result;
  std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
  if (!pipe) {
    throw std::runtime_error("popen() failed!");
  }
  while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
    result += buffer.data();
  }
  // Remove trailing newline
  if (!result.empty() && result.back() == '\n') {
    result.pop_back();
  }
  return result;
}

sysinfo get_sysinfo() {
  sysinfo sys;
  sys.os = "Linux";

  try {
    sys.cpu = exec_command(
        "cat /proc/cpuinfo | grep 'model name' | uniq | sed 's/model name[[:blank:]]*:[[:blank:]]*//' | awk 1 ORS=' '");
    sys.ram = exec_command(
        "cat /proc/meminfo | grep 'MemTotal' | sed 's/MemTotal:[[:blank:]]*//' | awk '{$1=$1/1024^2; print "
        "$1,\"GB\";}' | awk 1 ORS=' '");
  } catch (const std::runtime_error& e) {
    std::cerr << "Failed to get system information: " << e.what() << std::endl;
  }

  return sys;
}

std::vector<process_info> get_process_info(const std::vector<std::string>& process_names) {
  std::vector<process_info> processes;
  DIR* dir = opendir("/proc");
  struct dirent* entry;

  while ((entry = readdir(dir)) != nullptr) {
    if (entry->d_type == DT_DIR) {
      std::string pid_str(entry->d_name);
      if (std::all_of(pid_str.begin(), pid_str.end(), ::isdigit)) {
        int pid = std::stoi(pid_str);
        std::string comm_file = "/proc/" + pid_str + "/comm";
        std::ifstream comm_stream(comm_file);
        std::string name;
        std::getline(comm_stream, name);
        if (std::find(process_names.begin(), process_names.end(), name) != process_names.end()) {
          process_info proc;
          proc.pid = pid;
          proc.name = name;

          std::string stat_file = "/proc/" + pid_str + "/stat";
          std::ifstream stat_stream(stat_file);
          if (stat_stream.is_open()) {
            std::string ignore;
            double utime, stime;
            for (int i = 0; i < 13; ++i) {
              stat_stream >> ignore;
            }
            stat_stream >> utime >> stime;

            long total_time = utime + stime;
            long hertz = sysconf(_SC_CLK_TCK);
            proc.cpu_usage = (total_time / (double)hertz);

            std::string status_file = "/proc/" + pid_str + "/status";
            std::ifstream status_stream(status_file);
            std::string line;
            while (std::getline(status_stream, line)) {
              if (line.find("VmRSS:") == 0) {
                proc.mem_usage = line.substr(6);
                break;
              }
            }

            processes.push_back(proc);
          }
        }
      }
    }
  }
  closedir(dir);
  return processes;
}

int main() {
  sysinfo sys = get_sysinfo();
  std::cout << "Operating System: " << sys.os << std::endl;
  std::cout << "CPU: " << sys.cpu << std::endl;
  std::cout << "RAM: " << sys.ram << std::endl;

  std::vector<std::string> process_names = {"sshd"};
  std::vector<process_info> processes = get_process_info(process_names);

  std::cout << "\nProcess List:" << std::endl;
  for (const auto& proc : processes) {
    std::cout << "PID: " << proc.pid << ", Name: " << proc.name << ", CPU Usage: " << proc.cpu_usage
              << " sec, Memory Usage: " << proc.mem_usage << std::endl;
  }

  return 0;
}

2.2 代码解析

  1. 结构体定义

    • sysinfo:用于存储系统信息,包括操作系统、CPU和内存信息。
    • process_info:用于存储进程信息,包括PID、名称、CPU使用时间和内存使用情况。
  2. 获取系统信息

    • get_sysinfo函数获取系统的操作系统、CPU和内存信息。
  3. 获取特定进程信息

    • get_process_info函数遍历/proc文件系统,查找指定名称的进程,并提取其PID、CPU和内存使用情况。
  4. 主函数

    • 调用系统信息和进程信息函数,并打印结果。

2.3 运行效果

g++ -o mytest mytest.cpp -std=c++14编译并运行程序后:

./mytest 
Operating System: Linux
CPU: AMD Ryzen 5 3500U with Radeon Vega Mobile Gfx
RAM: 3.77756 GB

Process List:
PID: 1331, Name: sshd, CPU Usage: 0.01 sec, Memory Usage: 7808 kB
PID: 1332, Name: sshd, CPU Usage: 0.03 sec, Memory Usage: 7792 kB
PID: 1446, Name: sshd, CPU Usage: 2.14 sec, Memory Usage: 6956 kB
PID: 1495, Name: sshd, CPU Usage: 0.02 sec, Memory Usage: 8688 kB
PID: 1550, Name: sshd, CPU Usage: 0.67 sec, Memory Usage: 7344 kB

2.4 实现方式优劣势

优势

  • 简单易读 :通过执行系统命令获取信息,代码更简洁,易于理解和维护。
  • 复用现有工具 :利用已有的系统命令,如catgrep,不需要自己解析复杂的文件内容。

劣势

  • 效率低下 :每次获取信息都需要创建新进程执行命令,带来了额外的系统开销。
  • 依赖外部命令 :依赖于系统上存在特定的命令,并且这些命令的输出格式不能保证在所有系统上都一致。
  • 安全性问题 :使用popen执行命令可能带来安全风险,特别是在处理不受信任的输入时。

考虑以上方案的缺陷,更推荐如下文章的实现 Linux编程:进程保活,自动重启与资源监控的实现.

举报

相关推荐

0 条评论