使用C++设计开发一个功能完善的多进程管理器
目录
- 引言
- 核心功能需求
- 系统架构设计
- 进程配置结构
- 进程状态管理
- 进程管理器实现
- 类定义
- 构造与析构
- 添加进程配置
- 依赖关系排序
- 启动进程
- 停止进程
- 进程监控与自动重启
- 使用示例
- 基本使用
- 高级用法:信号处理
- 进阶特性
- 日志记录
- 健康检查
- 资源限制
- 性能优化建议
- 常见问题与解决方案
- 问题1: 进程启动失败
- 问题2: 僵尸进程
- 问题3: 循环依赖
- 总结
- 附录: 完整源代码
- ProcessManager.h
- ProcessManager.cpp
- main.cpp (基本示例)
- CMakeLists.txt (编译配置)
- 编译和运行
- Makefile (简单编译方式)
- 使用说明
- 注意事项
引言
在实际的软件开发中,我们经常需要管理多个相互协作的进程。一个健壮的多进程管理器不仅需要能够按照依赖顺序启动进程,还要能够优雅地停止进程,并在进程意外崩溃时自动重启。本文将详细介绍如何使用C++开发一个功能完善的多进程管理器。
核心功能需求
一个完整的多进程管理器应该具备以下核心功能:
- 进程顺序启动: 根据进程间的依赖关系,按照正确的顺序启动各个进程
- 进程停止管理: 能够优雅地停止进程,并处理停止失败的情况
- 崩溃自动重启: 监控进程状态,在进程异常退出时自动重启
系统架构设计
进程配置结构
首先,我们需要定义进程的配置信息:
#include <string> #include <vector> #include <memory> struct ProcessConfig { std::string name; // 进程名称 std::string executable; // 可执行文件路径 std::vector<std::string> args; // 启动参数 int startDelay; // 启动延迟(毫秒) int maxRestarts; // 最大重启次数 bool autoRestart; // 是否自动重启 std::vector<std::string> dependencies; // 依赖的进程 };
进程状态管理
定义进程的运行状态:
enum class ProcessState { STOPPED, // 已停止 STARTING, // 启动中 RUNNING, // 运行中 STOPPING, // 停止中 CRASHED // 已崩溃 }; struct ProcessInfo { ProcessConfig config; pid_t pid; ProcessState state; int restartCount; std::chrono::system_clock::time_point lastStartTime; std::chrono::system_clock::time_point lastCrashTime; };
进程管理器实现
类定义
#include <map> #include <thread> #include <mutex> #include <condition_variable> #include <atomic> #include <signal.h> #include <sys/wait.h> #include <unistd.h> class ProcessManager { public: ProcessManager(); ~ProcessManager(); // 添加进程配置 bool addProcess(const ProcessConfig& config); // 启动所有进程 bool startAll(); // 启动指定进程 bool startProcess(const std::string& name); // 停止所有进程 void stopAll(); // 停止指定进程 bool stopProcess(const std::string& name); // 获取进程状态 ProcessState getProcessState(const std::string& name) const; // 启动监控线程 void startMonitoring(); private: // 按依赖顺序排序进程 std::vector<std::string> getStartOrder(); // 实际启动进程 pid_t launchProcess(ProcessInfo& info); // 监控进程状态 void monitorProcesses(); // 重启崩溃的进程 void restartProcess(const std::string& name); // 检查进程是否存活 bool isProcessAlive(pid_t pid); std::map<std::string, ProcessInfo> processes_; std::mutex mutex_; std::atomic<bool> running_; std::thread monitorThread_; };
构造与析构
ProcessManager::ProcessManager() : running_(false) { } ProcessManager::~ProcessManager() { stopAll(); if (monitorThread_.joinable()) { running_ = false; monitorThread_.join(); } }
添加进程配置
bool ProcessManager::addProcess(const ProcessConfig& config) { std::lock_guard<std::mutex> lock(mutex_); if (processes_.find(config.name) != processes_.end()) { std::cerr << "Process " << config.name << " already exists" << std::endl; return false; } ProcessInfo info; info.config = config; info.pid = -1; info.state = ProcessState::STOPPED; info.restartCount = 0; processes_[config.name] = info; return true; }
依赖关系排序
使用拓扑排序算法确定进程启动顺序:
std::vector<std::string> ProcessManager::getStartOrder() { std::vector<std::string> order; std::map<std::string, int> inDegree; std::map<std::string, std::vector<std::string>> graph; // 初始化入度 for (const auto& pair : processes_) { inDegree[pair.first] = 0; } // 构建依赖图 for (const auto& pair : processes_) { const std::string& name = pair.first; const auto& deps = pair.second.config.dependencies; for (const auto& dep : deps) { graph[dep].push_back(name); inDegree[name]++; } } // 拓扑排序 std::vector<std::string> queue; for (const auto& pair : inDegree) { if (pair.second == 0) { queue.push_back(pair.first); } } while (!queue.empty()) { std::string current = queue.back(); queue.pop_back(); order.push_back(current); for (const auto& next : graph[current]) { inDegree[next]--; if (inDegree[next] == 0) { queue.push_back(next); } } } // 检查是否有循环依赖 if (order.size() != processes_.size()) { std::cerr << "Circular dependency detected!" << std::endl; order.clear(); } return order; }
启动进程
pid_t ProcessManager::launchProcess(ProcessInfo& info) { pid_t pid = fork(); if (pid < 0) { std::cerr << "Failed to fork process: " << info.config.name << std::endl; return -1; } if (pid == 0) { // 子进程 std::vector<char*> argv; argv.push_back(const_cast<char*>(info.config.executable.c_str())); for (auto& arg : info.config.args) { argv.push_back(const_cast<char*>(arg.c_str())); } argv.push_back(nullptr); execv(info.config.executable.c_str(), argv.data()); // 如果execv返回,说明执行失败 std::cerr << "Failed to execute: " << info.config.executable << std::endl; exit(1); } // 父进程 return pid; } bool ProcessManager::startProcess(const std::string& name) { std::lock_guard<std::mutex> lock(mutex_); auto it = processes_.find(name); if (it == processes_.end()) { std::cerr << "Process not found: " << name << std::endl; return false; } ProcessInfo& info = it->second; if (info.state == ProcessState::RUNNING) { std::cout << "Process already running: " << name << std::endl; return true; } // 检查依赖进程是否已启动 for (const auto& dep : info.config.dependencies) { auto depIt = processes_.find(dep); if (depIt == processes_.end() || depIt->second.state != ProcessState::RUNNING) { std::cerr << "Dependency not running: " << dep << std::endl; re编程turn false; } } info.state = ProcessState::STARTING; // 启动延迟 if (info.config.startDelay > 0) { std::this_thread::sleep_for( std::chrono::milliseconds(info.config.startDelay)); } pid_t pid = launchProcess(info); if (pid < 0) { info.state = ProcessState::STOPPED; return false; } info.pid = pid; info.state = ProcessState::RUNNING; info.lastStartTime = std::chrono::system_clock::now(); std::cout << "Started process: " << name << " (PID: " << pid << ")" << std::endl; return true; } bool ProcessManager::startAll() { std::vector<std::string> order = getStartOrder(); if (order.empty()) { return false; } for (const auto& name : order) { if (!startProcess(name)) { std::cerr << "Failed to start process: " << name << std::endl; return false; } } return true; }
停止进程
bool ProcessManager::stopProcess(const std::string& name) { std::lock_guard<std::mutex> lock(mutex_); auto it = processes_.find(name); if (it == processes_.end()) { return false; } ProcessInfo& info = it->second; if (info.state != ProcessState::RUNNING) { return true; } info.state = ProcessState::STOPPING; // 发送SIGTERM信号 if (kill(info.pid, SIGTERM) == 0) { // 等待进程优雅退出 int status; pid_t result = waitpid(info.pid, &status, WNOHANG); if (result == 0) { // 进程还在运行,等待一段时间 std::this_thread::sleep_for(std::chrono::seconds(5)); // 再次检查 result = waitpid(info.pid, &status, WNOHANG); if (result == 0) { // 强制终止 std::cout << "Force killing process: " << name << std::endl; kill(info.pid, SIGKILL); waitpid(info.pid, &status, 0); } } } info.pid = -1; info.state = ProcessState::STOPPED; std::cout << "Stopped process: " << name << std::endl; return true; } void ProcessManager::stopAll() { // 按照启动顺序的反序停止进程 std::vector<std::string> order = getStartOrder(); std::reverse(order.begin(), order.end()); for (const auto& name : order) { stopProcess(name); } }
进程监控与自动重启
bool ProcessManager::isProcessAlive(pid_t pid) { if (pid <= 0) { return false; } int status; pid_t result = waitpid(pid, &status, WNOHANG); if (result == 0) { // 进程仍在运行 return true; } else if (result == pid) { // 进程已退出 return false; } else { // 错误 return false; } } void ProcessManager::restartProcess(const std::string& name) { std::lock_guard<std::mutex> lock(mutex_); auto it = processes_.find(name); if (it == processes_.end()) { return; } ProcessInfo& info = it->second; // 检查重启次数限制 if (info.restartCount >= info.config.maxRestarts) { std::cerr << "Max restart count reached for: " << name << std::endl; info.state = ProcessState::STOPPED; return; } info.restartCount++; info.lastCrashTime = std::chrono::system_clock::now(); std::cout << "Restarting process: " << name << " (attempt " << info.restartCount << ")" << std::endl; // 等待一小段时间再重启,避免快速重启循环 std::this_thread::sleep_for(std::chrono::seconds(1)); info.state = ProcessState::STARTING; pid_t pid = launchProcess(info); if (pid > 0) { info.pid = pid; info.state = ProcessState::RUNNING; info.lastStartTime = std::chrono::system_clock::now(); std::cout << "Restarted process: " << name << " (PID: " << pid << ")" << std::endl; } else { info.state = ProcessState::CRASHED; std::cerr << "Failed to restart process: " << name << std::endl; } } void ProcessManager::monitorProcesses() { while (running_) { std::this_thread::sleep_for(std::chrono::seconds(1)); std::lock_guard<std::mutex> lock(mutex_); for (auto& pair : processes_) { ProcessInfo& info = pair.second; if (info.state == ProcessState::RUNNING) { if (!isProcessAlive(info.pid)) { std::cerr << "Process crashed: " << pair.first << std::endl; info.state = ProcessState::CRASHED; if (info.config.autoRestart) { // 解锁后重启,避免死锁 std::string name = pair.first; mutex_.unlock(); restartProcess(name); mutex_.lock(); } } } } } } void ProcessManager::startMonitoring() { running_ = true; monitorThread_ = std::thread(&ProcessManager::monitorProcesses, this); } ProcessState ProcessManager::getProcessState(const std::string& name) const { std::lock_guard<std::mutex> lock(mutex_); auto it = processes_.find(name); if (it == processes_.end()) { return ProcessState::STOPPED; } return it->second.state; }
使用示例
基本使用
#include "ProcessManager.h" int main() { ProcessManager manager; // 配置数据库进程 ProcessConfig dbConfig; dbConfig.name = "database"; dbConfig.executable = "/usr/bin/postgres"; dbConfig.args = {"-D", "/var/lib/PostgreSQL/data"}; dbConfig.startDelay = 0; dbConfig.maxRestarts = 3; dbConfig.autoRestart = true; // 配置应用服务进程(依赖数据库) ProcessConfig appConfig; appConfig.name = "app_server"; appConfig.executable = "/opt/myapp/server"; appConfig.args = {"--port", "8080"}; appConfig.startDelay = 2000; // 等待数据库启动 appConfig.maxRestarts = 5; appConfig.autoRestart = true; appConfig.dependencies = {"database"}; // 配置Web服务进程(依赖应用服务) ProcessConfig webConfig; webConfig.name = "web_server"; webConfig.executable = "/usr/sbin/nginx"; webConfig.args = {"-c", "/etc/nginx/nginx.conf"}; webConfig.startDelay = 1000; webConfig.maxRestarts = 3; webConfig.autoRestart = true; webConfig.dependencies = {"app_server"}; // 添加进程配置 manager.addProcess(dbConfig); manager.addProcess(appConfig); manager.addProcess(webConfig); // 启动所有进程 if (manager.startAll()) { std::cout << "All processes started successfully" << std::endl; } else { std::cerr << "Failed to start some processes" << std::endl; return 1; } // 启动监控线程 manager.startMonitoring(); // 等待用户输入停止信号 std::cout << "Press Enter to stop all processes..." << std::endl; std::cin.get(); // 停止所有进程 manager.stopAll(); return 0; }
高级用法:信号处理
#include <csignal> ProcessManager* g_manager = nullptr; void signalHandler(int signal) { if (signal == SIGINT || signal == SIGTERM) { std::cout << "\nReceived shutdown signal..." << std::endl; if (g_manager) { g_manager->stopAll(); } exit(0); } } int main() { ProcessManager manager; g_manager = &manager; // 注册信号处理器 signal(SIGINT, signalHandler); signal(SIGTERM, signalHandler); // ... 配置和启动进程 ... manager.startMonitoring(); // 保持运行 while (true) { std::this_thread::sleep_for(std::chrono::seconds(1)); } return 0; }
进阶特性
日志记录
为了更好地追踪进程状态,可以添加日志功能:
class Logger { public: static void log(const std::string& level, const std::string& message) { auto now = std::chrono::system_clock::now(); auto time = std::chrono::system_clock::to_time_t(now); std::cout << "[" << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S") << "] [" << level << "] " << message << std::endl; } static void info(const std::string& message) { log("INFO", message); } static void warn(const std::string& message) { log("WARN", message); } static void error(const std::string& message) { log("ERROR", message); } };
健康检查
实现进程健康检查机制:
struct HealthCheck { std::string type; // "http", "tcp", "script" std::string target; int interval; // 检查间隔(秒) int timeout; // 超时时间(秒) }; // 在ProcessConfig中添加 HealthCheck healthCheck;
资源限制
python使用setrlimit
限制进程资源:
void setProcessLimits() { struct rlimit limit; // 限制内存 limit.rlim_cur = 512 * 1024 * 1024; // 512MB limit.rlim_max = 1024 * 1024 * 1024; // 1GB setrlimit(RLIMIT_AS, &limit); // 限制CPU时间 limit.rlim_cur = 3600; // 1小时 limit.rlim_max = 7200; // 2小时 setrlimit(RLIMIT_CPU, &limit); }
性能优化建议
- 使用epoll监控进程: 对于大量进程,使用epoll而不是轮询可以提高效率
- 进程池管理: 预创建进程池以减少启动时间
- 配置文件支持: 使用jsON或YAML配置文件管理进程配置
- 进程分组: 将相关进程分组管理,支持按组启动停止
- 优雅重启: 实现热重启功能,避免服务中断
常见问题与解决方案
问题1: 进程启动失败
原因: 可执行文件路径错误、权限不足、依赖库缺失
解决方案:
- 验证可执行文件路径和权限
- 使用
ldd
检查依赖库 - 添加详细的错误日志
问题2: 僵尸进程
原因: 父进程未及时调用waitpid
回收子进程
解决方案:
// 注册SIGCHLD信号处理器 signal(SIGCHLD, [](int) { int status; while (waitpid(-1, &status, WNOHANG) > 0); });
问题3: 循环依赖
原因: 进程依赖关系配置错误
解决方案:
- 在启动前进行依赖关系检查
- 使用拓扑排序检测循环依赖
- 提供清晰的错误提示
总结
本文详细介绍了如何使用C++开发一个功能完整的多进程管理器,涵盖了进程顺序启动、优雅停止和崩溃自动重启等核心功能。通过合理的架构设计和实现,我们可以构建一个稳定可靠的进程管理系统。
在实际应用中,可以根据具体需求进一步扩展功能,如添加Web界面、集成监控告警、支持分布式部署等。希望本文能够为你的项目开发提供有价值的参考。
附录: 完整源代码
ProcessManager.h
#ifndef PROCESS_MANAGER_H #define PROCESS_MANAGER_H #include <string> #include <vector> #include <map> #include <memory> #include <thread> #include <mutex> #include <atomic> #include <chrono> #include <sys/types.h> // 进程配置结构 struct ProcessConfig { std::string name; // 进程名称 std::string executable; // 可执行文件路径 std::vector<std::string> args; // 启动参数 int startDelay; // 启动延迟(毫秒) int maxRestarts; // 最大重启次数 bool autoRestart; // 是否自动重启 std::vector<std::string> dependencies; // 依赖的进程 ProcessConfig() : startDelay(0), maxRestarts(3), autoRestart(true) {} }; // 进程状态枚举 enum class ProcessState { STOPPED, // 已停止 STARTING, // 启动中 RUNNING, // 运行中 STOPPING, // 停止中 CRASHED // 已崩溃 }; // 进程信息结构 struct ProcessInfo { ProcessConfig config; pid_t pid; ProcessState state; int restartCount; std::chrono::system_clock::time_point lastStartTime; std::chrono::system_clock::time_point lastCrashTime; ProcessInfo() : pid(-1), state(ProcessState::STOPPED), restartCount(0) {} }; // 进程管理器类 class ProcessManager { public: ProcessManager(); ~ProcessManager(); // 添加进程配置 bool addProcess(const ProcessConfig& config); // 启动所有进程 bool startAll(); // 启动指定进程 bool startProcess(const std::string& name); // 停止所有进程 void stopAll(); //编程客栈 停止指定进程 bool stopProcess(const std::string& name); // 获取进程状态 ProcessState getProcessState(const std::string& name) const; // 启动监控线程 void startMonitoring(); // 停止监控线程 void stopMonitoring(); private: // 按依赖顺序排序进程 std::vector<std::string> getStartOrder(); // 实际启动进程 pid_t launchProcess(ProcessInfo& info); // 监控进程状态 void monitorProcesses(); // 重启崩溃的进程 void restartProcess(const std::string& name); // 检查进程是否存活 bool isProcessAlive(pid_t pid); std::map<std::string, ProcessInfo> processes_; mutable std::mutex mutex_; std::atomic<bool> running_; std::thread monitorThread_; }; #endif // PROCESS_MANAGER_H
ProcessManager.cpp
#include "ProcessManager.h" #include <IOStream> #include <algorithm> #include <signal.h> #include <sys/wait.h> #include <unistd.h> ProcessManager::ProcessManager() : running_(false) { } ProcessManager::~ProcessManager() { stopMonitoring(); stopAll(); } bool ProcessManager::addProcess(const ProcessConfig& config) { std::lock_guard<std::mutex> lock(mutex_); if (processes_.find(config.name) != processes_.end()) { std::cerr << "Process " << config.name << " already exists" << std::endl; return false; } ProcessInfo info; info.config = config; info.pid = -1; info.state = ProcessState::STOPPED; info.restartCount = 0; processes_[config.name] = info; return true; } std::vector<std::string> ProcessManager::getStartOrder() { std::vector<std::string> order; std::map<std::string, int> inDegree; std::map<std::string, std::vector<std::string>> graph; // 初始化入度 for (const auto& pair : processes_) { inDegree[pair.first] = 0; } // 构建依赖图 for (const auto& pair : processes_) { const std::string& name = pair.first; const auto& deps = pair.second.config.dependencies; for (const auto& dep : deps) { if (processes_.find(dep) == processes_.end()) { std::cerr << "Dependency not found: " << dep << std::endl; return std::vector<std::string>(); } graph[dep].push_back(name); inDegree[name]++; } } // 拓扑排序 std::vector<std::string> queue; for (const auto& pair : inDegree) { if (pair.second == 0) { queue.push_back(pair.first); } } while (!queue.empty()) { std::string current = queue.back(); queue.pop_back(); order.push_back(current); for (const auto& next : graph[current]) { inDegree[next]--; if (inDegree[next] == 0) { queue.push_back(next); } } } // 检查是否有循环依赖 if (order.size() != processes_.size()) { std::cerr << "Circular dependency detected!" << std::endl; order.clear(); } return order; } pid_t ProcessManager::launchProcess(ProcessInfo& info) { pid_t pid = fork(); if (pid < 0) { std::cerr << "Failed to fork process: " << info.config.name << std::endl; return -1; } if (pid == 0) { // 子进程 std::vector<char*> argv; argv.push_back(const_cast<char*>(info.config.executable.c_str())); for (auto& arg : info.config.args) { argv.push_back(const_cast<char*>(arg.c_str())); } argv.push_back(nullptr); execv(info.config.executable.c_str(), argv.data()); // 如果execv返回,说明执行失败 std::cerr << "Failed to execute: " << info.config.executable << std::endl; exit(1); } // 父进程 return pid; } bool ProcessManager::startProcess(const std::string& name) { std::lock_guard<std::mutex> lock(mutex_); auto it = processes_.find(name); if (it == processes_.end()) { std::cerr << "Process not found: " << name << std::endl; return false; } ProcessInfo& info = it->second; if (info.state == ProcessState::RUNNING) { std::cout << "Process already running: " << name << std::endl; return true; } // 检查依赖进程是否已启动 for (const auto& dep : info.config.dependencies) { auto depIt = processes_.find(dep); if (depIt == processes_.end() || depIt->second.state != ProcessState::RUNNING) { std::cerr << "Dependency not running: " << dep << std::endl; return false; } } info.state = ProcessState::STARTING; // 启动延迟 if (info.config.startDelay > 0) { std::this_thread::sleep_for( std::chrono::milliseconds(info.config.startDelay)); } pid_t pid = launchProcess(info); if (pid < 0) { info.state = ProcessState::STOPPED; return false; } info.pid = pid; info.state = ProcessState::RUNNING; info.lastStartTime = std::chrono::system_clock::now(); std::cout << "Started process: " << name << " (PID: " << pid << ")" << std::endl; return true; } bool ProcessManager::startAll() { std::vector<std::string> order = getStartOrder(); if (order.empty()) { return false; } for (const auto& name : order) { if (!startProcess(name)) { std::cerr << "Failed to start process: " << name << std::endl; return false; } } return true; } bool ProcessManager::stopProcess(const std::string& name) { std::lock_guard<std::mutex> lock(mutex_); auto it = processes_.find(name); if (it == processes_.end()) { return false; } ProcessInfo& info = it->second; if (info.state != ProcessState::RUNNING) { return true; } info.state = ProcessState::STOPPING; // 发送SIGTERM信号 if (kill(info.pid, SIGTERM) == 0) { // 等待进程优雅退出 int status; pid_t result = waitpid(info.pid, &status, WNOHANG); if (result == 0) { // 进程还在运行,等待一段时间 std::this_thread::sleep_for(std::chrono::seconds(5)); // 再次检查 result = waitpid(info.pid, &status, WNOHANG); if (result == 0) { // 强制终止 std::cout << "Force killing process: " << name << std::endl; kill(info.pid, SIGKILL); waitpid(info.pid, &status, 0); } } } info.pid = -1; info.state = ProcessState::STOPPED; std::cout << "Stopped process: " << name << std::endl; return true; } void ProcessManager::stopAll() { // 按照启动顺序的反序停止进程 std::vector<std::string> order = getStartOrder(); std::reverse(order.begin(), order.end()); for (const auto& name : order) { stopProcess(name); } } bool ProcessManager::isProcessAlive(pid_t pid) { if (pid <= 0) { return false; } int status; pid_t result = waitpid(pid, &status, WNOHANG); if (result == 0) { // 进程仍在运行 return true; } else if (result == pid) { // 进程已退出 return false; } else { // 错误 return false; } } void ProcessManager::restartProcess(const std::string& name) { std::lock_guard<std::mutex> lock(mutex_); auto it = processes_.find(name); if (it == processes_.end()) { return; } ProcessInfo& info = it->second; // 检查重启次数限制 if (info.restartCount >= info.config.maxRestarts) { std::cerr << "Max restart count reached for: " << name << std::endl; info.state = ProcessState::STOPPED; return; } info.restartCount++; info.lastCrashTime = std::chrono::system_clock::now(); std::cout << "Restarting process: " << name << " (attempt " << info.restartCount << ")" << std::endl; // 等待一小段时间再重启,避免快速重启循环 std::this_thread::sleep_for(std::chrono::seconds(1)); info.state = ProcessState::STARTING; pid_t pid = launchProcess(info); if (pid > 0) { info.pid = pid; info.state = ProcessState::RUNNING; info.lastStartTime = std::chrono::system_clock::now(); std::cout << "Restarted process: " << name << " (PID: " << pid << ")" << std::endl; } else { info.state = ProcessState::CRASHED; std::cerr << "Failed to restart process: " << name << std::endl; } } void ProcessManager::monitorProcesses() { while (running_) { std::this_thread::sleep_for(std::chrono::seconds(1)); std::vector<std::string> crashedProcesses; { std::lock_guard<std::mutex> lock(mutex_); for (auto& pair : processes_) { ProcessInfo& info = pair.second; if (info.state == ProcessState::RUNNING) { if (!isProcessAlive(info.pid)) { std::cerr << "Process crashed: " << pair.first << std::endl; info.state = ProcessState::CRASHED; if (info.config.autoRestart) { crashedProcesses.push_back(pair.first); } } } } } // 在锁外重启进程,避免死锁 for (const auto& name : crashedProcesses) { restartProcess(name); } } } void ProcessManager::startMonitoring() { if (!running_) { running_ = true; monitorThread_ = std::thread(&ProcessManager::monitorProcesses, this); } } void ProcessManager::stopMonitoring() { if (running_) { running_ = false; if (monitorThread_.joinable()) { monitorThread_.join(); } } } ProcessState ProcessManager::getProcessState(const std::string& name) const { std::lock_guard<std::mutex> lock(mutex_); auto it = processes_.find(name); if (it == processes_.end()) { return ProcessState::STOPPED; } return it->second.state; }
main.cpp (基本示例)
#include "ProcessManager.h" #include <iostream> #include <csignal> ProcessManager* g_manager = nullptr; void signalHandler(int signal) { if (signal == SIGINT || signal == SIGTERM) { std::cout << "\nReceived shutdown signal..." << std::endl; if (gpython_manager) { g_manager->stopAll(); } exit(0); } } int main() { ProcessManager manager; g_manager = &manager; // 注册信号处理器 signal(SIGINT, signalHandler); signal(SIGTERM, signalHandler); // 配置数据库进程 ProcessConfig dbConfig; dbConfig.name = "database"; dbConfig.executable = "/usr/bin/postgres"; dbConfig.args = {"-D", "/var/lib/postgresql/data"}; dbConfig.startDelay = 0; dbConfig.maxRestarts = 3; dbConfig.autoRestart = true; // 配置应用服务进程(依赖数据库) ProcessConfig appConfig; appConfig.name = "app_server"; appConfig.executable = "/opt/myapp/server"; appConfig.args = {"--port", "8080"}; appConfig.startDelay = 2000; // 等待数据库启动 appConfig.maxRestarts = 5; appConfig.autoRestart = true; appConfig.dependencies = {"database"}; // 配置Web服务进程(依赖应用服务) ProcessConfig webConfig; webConfig.name = "web_server"; webConfig.executable = "/usr/sbin/nginx"; webConfig.args = {"-c", "/etc/nginx/nginx.conf"}; webConfig.startDelay = 1000; webConfig.maxRestarts = 3; webConfig.autoRestart = true; webConfig.dependencies = {"app_server"}; // 添加进程配置 manager.addProcess(dbConfig); manager.addProcess(appConfig); manager.addProcess(webConfig); // 启动所有进程 if (manager.startAll()) { std::cout << "All processes started successfully" << std::endl; } else { std::cerr <js;< "Failed to start some processes" << std::endl; return 1; } // 启动监控线程 manager.startMonitoring(); std::cout << "Process manager is running. Press Ctrl+C to stop..." << std::endl; // 保持运行 while (true) { std::this_thread::sleep_for(std::chrono::seconds(1)); } return 0; }
CMakeLists.txt (编译配置)
cmake_minimum_required(VERSION 3.10) project(ProcessManager) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 添加编译选项 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pthread") # 源文件 set(SOURCES ProcessManager.cpp main.cpp ) # 头文件 set(HEADERS ProcessManager.h ) # 创建可执行文件 add_executable(process_manager ${SOURCES} ${HEADERS}) # 链接pthread库 target_link_libraries(process_manager pthread)
编译和运行
# 创建构建目录 mkdir build cd build # 运行CMake cmake .. # 编译 make # 运行 ./process_manager
Makefile (简单编译方式)
CXX = g++ CXXFLAGS = -std=c++11 -Wall -Wextra -pthread TARGET = process_manager SOURCES = ProcessManager.cpp main.cpp HEADERS = ProcessManager.h OBJECTS = $(SOURCES:.cpp=.o) .PHONY: all clean all: $(TARGET) $(TARGET): $(OBJECTS) $(CXX) $(CXXFLAGS) -o $@ $^ %.o: %.cpp $(HEADERS) $(CXX) $(CXXFLAGS) -c $< -o $@ clean: rm -f $(OBJECTS) $(TARGET) run: $(TARGET) ./$(TARGET)
使用说明
编译项目:
make
运行管理器:
./process_manager
停止管理器: 按 Ctrl+C
或发送 SIGTERM 信号
注意事项
需要在linux环境下编译运行
确保有足够的权限启动配置的进程
根据实际需求修改进程配置
可执行文件路径必须是绝对路径
建议在生产环境中添加更完善的错误处理和日志记录
以上就是使用C++设计开发一个功能完善的多进程管理器的详细内容,更多关于C++多进程管理器的资料请关注编程客栈(www.devze.com)其它相关文章!
精彩评论