C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++多进程管理器

使用C++设计开发一个功能完善的多进程管理器

作者:天天进步2015

一个健壮的多进程管理器不仅需要能够按照依赖顺序启动进程,还要能够优雅地停止进程,并在进程意外崩溃时自动重启,本文将详细介绍如何使用C++开发一个功能完善的多进程管理器,需要的可以了解下

引言

在实际的软件开发中,我们经常需要管理多个相互协作的进程。一个健壮的多进程管理器不仅需要能够按照依赖顺序启动进程,还要能够优雅地停止进程,并在进程意外崩溃时自动重启。本文将详细介绍如何使用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;
            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::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;

资源限制

使用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);
}

性能优化建议

常见问题与解决方案

问题1: 进程启动失败

原因: 可执行文件路径错误、权限不足、依赖库缺失

解决方案:

问题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 (g_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 << "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++多进程管理器的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文