开发者

使用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)其它相关文章!

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新开发

        开发排行榜