当前位置: 代码网 > it编程>编程语言>C/C++ > 使用C++设计开发一个功能完善的多进程管理器

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

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

性能优化建议

  • 使用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 (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++多进程管理器的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com