Linux C++编程-实现进程的冻结与恢复管理模块

1. 概要

在Linux系统中,进程管理是核心组件,涵盖了创建、调度、暂停、恢复和终止等关键操作。
本文将详细介绍基于C++的进程管理工具的设计与实现,包括进程的查找、暂停、恢复和终止功能。

2. 进程管理接口详解

2.1 进程冻结与恢复的基本概念

在Linux环境中,进程的管理涉及到对进程执行状态的控制,其中包括了进程的冻结(暂停)和恢复(继续执行)。这些操作通过发送特定的信号来实现,主要使用到 SIGSTOPSIGCONT 信号。

2.2 进程查找与PID获取

为了准确控制目标进程,首先需要能够根据进程名称或者其他标识符获取到进程的PID。在Linux系统中,可以通过读取 /proc 文件系统来获取所有运行中进程的详细信息,包括进程的命令行参数和状态。

/**
 * @brief Function to find the PID of a process by its name
 * @param [in] processName  process name
 * @param [out] pid  process id
 * @return true - find pid by process name; false - not find pid by process name
 */
bool FindPidByProcessName(const std::string& processName, pid_t &pid);

2.3 进程冻结与恢复的实现

2.3.1 进程冻结

进程冻结通过发送 SIGSTOP 信号来实现,暂停进程的执行。实现方法包括使用 kill(pid, SIGSTOP) 函数调用,并等待进程状态确认操作成功。

/**
 * @brief freeze process by pid
 *
 * @param [in] pid - pid find by process name.
 * @return true - Freeze successfully; false - Freeze failed
 */
bool FreezeProcessByPid(pid_t pid);
开始
查找进程PID
是否找到PID
发送SIGSTOP信号
是否成功
等待进程状态确认
进程是否已停止
冻结成功
未找到进程
冻结失败
2.3.2 进程恢复

一旦进程被冻结,可以通过发送 SIGCONT 信号来恢复其执行。恢复过程中可能需要多次尝试,以确保进程成功从暂停状态恢复到执行状态。

/**
 * @brief try to resume a stopped process by pid
 *
 * @param [in] attempts - if resume failed, try another attempts times.
 * @param [in] pid - pid find by process name.
 * @return true - Resume successfully; false - Resume failed
 */
bool TryToResumeProcessByPid(pid_t pid, int attempts = 3);
开始
尝试发送SIGCONT信号
是否成功
等待进程状态确认
进程是否已恢复
恢复成功
再次尝试
恢复失败

2.4 进程终止

在某些情况下,需要强制终止一个进程以释放系统资源或确保安全性。可以使用 SIGKILL 信号立即终止进程的执行,但需要注意可能会造成数据丢失。

/**
 * @brief terminate a process
 *
 * @param [in] processName - process name.
 * @param [in] attempts - if resume failed, try another attempts times.
 * @return 0 -  successfully; -1 - not found process; -2 terminate failed
 *         -3 - Handle waitpid error
 */
int TerminateProcess(const std::string& processName, int attempts = 3);
开始
查找进程PID
是否找到PID
发送SIGKILL信号
是否成功
等待进程终止
进程是否已终止
终止成功
未找到进程
终止失败

2.5 进程状态监控与控制

在实现进程管理功能时,还需要监控进程的状态并根据需要进行控制。通过读取 /proc/[pid]/status 文件可以获取进程的详细状态信息,如是否处于停止状态。

/**
 * @brief Function to check if the process is not in stopped state
 *
 * @param [in] pid - pid find by process name
 * @return true - stopped; false - not stopped
 */
bool IsProcessStopped(pid_t pid);

3. 设计方案

本节将详细介绍如何设计并实现一个C++进程管理工具,包括查找、暂停、恢复和终止进程的功能。

3.1 文件和目录管理

为了实现进程查找功能,使用 <dirent.h> 头文件中的相关函数,通过读取 /proc 目录下的进程信息来获取进程的PID和命令行信息。

bool FindPidByProcessName(const std::string& processName, pid_t& pid) {
  DirCloser dir(opendir("/proc"));
  if (!dir.get()) {
    std::cerr << "Failed to open directory /proc" << std::endl;
    return false;
  }

  struct dirent* entry;
  while ((entry = readdir(dir.get())) != nullptr) {
    // Check if the entry is a directory and its name is numeric
    if (entry->d_type == DT_DIR) {
      std::string pidStr = entry->d_name;
      if (pidStr.find_first_not_of("0123456789") == std::string::npos) {
        // Read the "cmdline" file to get the process name
        std::string cmdlinePath = "/proc/" + pidStr + "/cmdline";
        std::ifstream cmdlineFile(cmdlinePath);
        FileCloser fileCloser(cmdlineFile);  // FileCloser to manage cmdlineFile
        if (cmdlineFile.is_open()) {
          std::stringstream cmdlineStream;
          cmdlineStream << cmdlineFile.rdbuf();
          std::string cmdLine = cmdlineStream.str();
          // Check if the process name matches
          if (cmdLine.find(processName) != std::string::npos) {
            pid = std::stoi(pidStr);
            return true;
          }
        } else {
          std::cerr << "Failed to open " << cmdlinePath << std::endl;
        }
      }
    }
  }

  return false;
}

3.2 进程状态监控与控制

通过 kill 系统调用发送信号来控制进程的状态,同时利用 /proc/[pid]/status 文件来获取进程的详细状态信息。

bool IsProcessStopped(pid_t pid) {
  std::ifstream statusStream(std::string("/proc/") + std::to_string(pid) + "/status");
  std::string line;
  std::regex stateRegex("^State:\\s+([^\\(]+)\\(");

  while (getline(statusStream, line)) {
    std::smatch match;
    if (std::regex_search(line, match, stateRegex)) {
      std::string state = match[1].str();  // Get the matched state string
      // Remove leading and trailing spaces using regex_replace
      state = std::regex_replace(state, std::regex("^\\s+|\\s+$"), "");

      if (state == "T") {
        std::cerr << "Process " << pid << " status is " << state << " is in stopped state.\n";
        return true;
      } else {
        std::cout << "Process " << pid << " status is " << state << " is not in stopped state.\n";
        return false;
      }
    }
  }
  return true;  // Error or process not found
}

3.3 进程管理接口

封装了对进程的操作函数,提供了友好的外部接口。

bool FreezeProcessByPid(pid_t pid) {
  if (kill(pid, SIGSTOP) == -1) {
    std::cerr << "Failed to send SIGSTOP to process, pid" << pid << std::endl;
    return false;
  } else {
    std::cout << "Success to send SIGSTOP to process " << pid << std::endl;
  }
  usleep(1000);  // sleep 1ms, wait for process status
  if (IsProcessStopped(pid)) {
    std::cerr << "Process " << pid << " freeze success." << std::endl;
    return true;
  }
  return false;
}

bool TryToResumeProcessByPid(pid_t pid, int attempts) {
  for (int i = 0; i < attempts; ++i) {
    if (kill(pid, SIGCONT) == 0) {
      usleep(1000);  // sleep 1ms, wait for process status

      if (!IsProcessStopped(pid)) {
        std::cout << "Process " << pid << " resumed successfully.\n";
        return true;
      }
      usleep(1000 * 100);  // sleep 100ms, wait for another try
    }
  }
  std::cout << "Failed to resume process " << pid << " after " << attempts << " attempts.\n";
  return false;
}

int TerminateProcess(const std::string& processName, int attempts) {
  pid_t pid;
  if (!FindPidByProcessName(processName, pid)) {
    std::cerr << "Cannot find process, " << processName << std::endl;
    return -1;
  }

  for (int i = 0; i < attempts; ++i) {
    if (kill(pid, SIGKILL) == 0) {
      std::cout << "Process with PID: " << pid << " has been terminated.\n";
      int status;
      if (waitpid(pid, &status, 0) == -1) {
        std::cerr << "Error waiting for process " << pid << ": " << strerror(errno) << std::endl;
        return -3;  // Handle waitpid error
      }
      return 0;
    } else {
      std::cerr << "Failed to kill process with PID: " << pid << std::endl;
    }
  }
  std::cerr << "Failed to kill process with PID: " << pid << " after " << attempts << " attempts.\n";
  return -2;  // Handle kill attempts failure
}
  • 28
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘色的喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值