目录
- 引言
- 核心功能需求
- 系统架构设计
- 进程配置结构
- 进程状态管理
- 进程管理器实现
- 类定义
- 构造与析构
- 添加进程配置
- 依赖关系排序
- 启动进程
- 停止进程
- 进程监控与自动重启
- 使用示例
- 基本使用
- 高级用法:信号处理
- 进阶特性
- 日志记录
- 健康检查
- 资源限制
- 性能优化建议
- 常见问题与解决方案
- 问题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)其它相关文章!
加载中,请稍侯......
精彩评论