最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用C++設(shè)計開發(fā)一個功能完善的多進程管理器

 更新時間:2025年10月22日 09:42:15   作者:天天進步2015  
一個健壯的多進程管理器不僅需要能夠按照依賴順序啟動進程,還要能夠優(yōu)雅地停止進程,并在進程意外崩潰時自動重啟,本文將詳細介紹如何使用C++開發(fā)一個功能完善的多進程管理器,需要的可以了解下

引言

在實際的軟件開發(fā)中,我們經(jīng)常需要管理多個相互協(xié)作的進程。一個健壯的多進程管理器不僅需要能夠按照依賴順序啟動進程,還要能夠優(yōu)雅地停止進程,并在進程意外崩潰時自動重啟。本文將詳細介紹如何使用C++開發(fā)一個功能完善的多進程管理器。

核心功能需求

一個完整的多進程管理器應(yīng)該具備以下核心功能:

  • 進程順序啟動: 根據(jù)進程間的依賴關(guān)系,按照正確的順序啟動各個進程
  • 進程停止管理: 能夠優(yōu)雅地停止進程,并處理停止失敗的情況
  • 崩潰自動重啟: 監(jiān)控進程狀態(tài),在進程異常退出時自動重啟

系統(tǒng)架構(gòu)設(shè)計

進程配置結(jié)構(gòu)

首先,我們需要定義進程的配置信息:

#include <string>
#include <vector>
#include <memory>

struct ProcessConfig {
    std::string name;              // 進程名稱
    std::string executable;        // 可執(zhí)行文件路徑
    std::vector<std::string> args; // 啟動參數(shù)
    int startDelay;                // 啟動延遲(毫秒)
    int maxRestarts;               // 最大重啟次數(shù)
    bool autoRestart;              // 是否自動重啟
    std::vector<std::string> dependencies; // 依賴的進程
};

進程狀態(tài)管理

定義進程的運行狀態(tài):

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;
};

進程管理器實現(xiàn)

類定義

#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);
    
    // 獲取進程狀態(tài)
    ProcessState getProcessState(const std::string& name) const;
    
    // 啟動監(jiān)控線程
    void startMonitoring();
    
private:
    // 按依賴順序排序進程
    std::vector<std::string> getStartOrder();
    
    // 實際啟動進程
    pid_t launchProcess(ProcessInfo& info);
    
    // 監(jiān)控進程狀態(tài)
    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_;
};

構(gòu)造與析構(gòu)

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;
}

依賴關(guān)系排序

使用拓撲排序算法確定進程啟動順序:

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;
    }
    
    // 構(gòu)建依賴圖
    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);
            }
        }
    }
    
    // 檢查是否有循環(huán)依賴
    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返回,說明執(zhí)行失敗
        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;
    
    // 發(fā)送SIGTERM信號
    if (kill(info.pid, SIGTERM) == 0) {
        // 等待進程優(yōu)雅退出
        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);
    }
}

進程監(jiān)控與自動重啟

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;
    
    // 檢查重啟次數(shù)限制
    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;
    
    // 等待一小段時間再重啟,避免快速重啟循環(huán)
    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;
    
    // 配置數(shù)據(jù)庫進程
    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;
    
    // 配置應(yīng)用服務(wù)進程(依賴數(shù)據(jù)庫)
    ProcessConfig appConfig;
    appConfig.name = "app_server";
    appConfig.executable = "/opt/myapp/server";
    appConfig.args = {"--port", "8080"};
    appConfig.startDelay = 2000; // 等待數(shù)據(jù)庫啟動
    appConfig.maxRestarts = 5;
    appConfig.autoRestart = true;
    appConfig.dependencies = {"database"};
    
    // 配置Web服務(wù)進程(依賴應(yīng)用服務(wù))
    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;
    }
    
    // 啟動監(jiān)控線程
    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;
}

進階特性

日志記錄

為了更好地追蹤進程狀態(tài),可以添加日志功能:

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

健康檢查

實現(xiàn)進程健康檢查機制:

struct HealthCheck {
    std::string type;  // "http", "tcp", "script"
    std::string target;
    int interval;      // 檢查間隔(秒)
    int timeout;       // 超時時間(秒)
};

// 在ProcessConfig中添加
HealthCheck healthCheck;

資源限制

使用setrlimit限制進程資源:

void setProcessLimits() {
    struct rlimit limit;
    
    // 限制內(nèi)存
    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);
}

性能優(yōu)化建議

  • 使用epoll監(jiān)控進程: 對于大量進程,使用epoll而不是輪詢可以提高效率
  • 進程池管理: 預(yù)創(chuàng)建進程池以減少啟動時間
  • 配置文件支持: 使用JSON或YAML配置文件管理進程配置
  • 進程分組: 將相關(guān)進程分組管理,支持按組啟動停止
  • 優(yōu)雅重啟: 實現(xiàn)熱重啟功能,避免服務(wù)中斷

常見問題與解決方案

問題1: 進程啟動失敗

原因: 可執(zhí)行文件路徑錯誤、權(quán)限不足、依賴庫缺失

解決方案:

  • 驗證可執(zhí)行文件路徑和權(quán)限
  • 使用ldd檢查依賴庫
  • 添加詳細的錯誤日志

問題2: 僵尸進程

原因: 父進程未及時調(diào)用waitpid回收子進程

解決方案:

// 注冊SIGCHLD信號處理器
signal(SIGCHLD, [](int) {
    int status;
    while (waitpid(-1, &status, WNOHANG) > 0);
});

問題3: 循環(huán)依賴

原因: 進程依賴關(guān)系配置錯誤

解決方案:

  • 在啟動前進行依賴關(guān)系檢查
  • 使用拓撲排序檢測循環(huán)依賴
  • 提供清晰的錯誤提示

總結(jié)

本文詳細介紹了如何使用C++開發(fā)一個功能完整的多進程管理器,涵蓋了進程順序啟動、優(yōu)雅停止和崩潰自動重啟等核心功能。通過合理的架構(gòu)設(shè)計和實現(xiàn),我們可以構(gòu)建一個穩(wěn)定可靠的進程管理系統(tǒng)。

在實際應(yīng)用中,可以根據(jù)具體需求進一步擴展功能,如添加Web界面、集成監(jiān)控告警、支持分布式部署等。希望本文能夠為你的項目開發(fā)提供有價值的參考。

附錄: 完整源代碼

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>

// 進程配置結(jié)構(gòu)
struct ProcessConfig {
    std::string name;              // 進程名稱
    std::string executable;        // 可執(zhí)行文件路徑
    std::vector<std::string> args; // 啟動參數(shù)
    int startDelay;                // 啟動延遲(毫秒)
    int maxRestarts;               // 最大重啟次數(shù)
    bool autoRestart;              // 是否自動重啟
    std::vector<std::string> dependencies; // 依賴的進程
    
    ProcessConfig() : startDelay(0), maxRestarts(3), autoRestart(true) {}
};

// 進程狀態(tài)枚舉
enum class ProcessState {
    STOPPED,    // 已停止
    STARTING,   // 啟動中
    RUNNING,    // 運行中
    STOPPING,   // 停止中
    CRASHED     // 已崩潰
};

// 進程信息結(jié)構(gòu)
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);
    
    // 獲取進程狀態(tài)
    ProcessState getProcessState(const std::string& name) const;
    
    // 啟動監(jiān)控線程
    void startMonitoring();
    
    // 停止監(jiān)控線程
    void stopMonitoring();
    
private:
    // 按依賴順序排序進程
    std::vector<std::string> getStartOrder();
    
    // 實際啟動進程
    pid_t launchProcess(ProcessInfo& info);
    
    // 監(jiān)控進程狀態(tài)
    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;
    }
    
    // 構(gòu)建依賴圖
    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);
            }
        }
    }
    
    // 檢查是否有循環(huán)依賴
    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返回,說明執(zhí)行失敗
        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;
    
    // 發(fā)送SIGTERM信號
    if (kill(info.pid, SIGTERM) == 0) {
        // 等待進程優(yōu)雅退出
        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;
    
    // 檢查重啟次數(shù)限制
    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;
    
    // 等待一小段時間再重啟,避免快速重啟循環(huán)
    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);
    
    // 配置數(shù)據(jù)庫進程
    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;
    
    // 配置應(yīng)用服務(wù)進程(依賴數(shù)據(jù)庫)
    ProcessConfig appConfig;
    appConfig.name = "app_server";
    appConfig.executable = "/opt/myapp/server";
    appConfig.args = {"--port", "8080"};
    appConfig.startDelay = 2000; // 等待數(shù)據(jù)庫啟動
    appConfig.maxRestarts = 5;
    appConfig.autoRestart = true;
    appConfig.dependencies = {"database"};
    
    // 配置Web服務(wù)進程(依賴應(yīng)用服務(wù))
    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;
    }
    
    // 啟動監(jiān)控線程
    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
)

# 創(chuàng)建可執(zhí)行文件
add_executable(process_manager ${SOURCES} ${HEADERS})

# 鏈接pthread庫
target_link_libraries(process_manager pthread)

編譯和運行

# 創(chuàng)建構(gòu)建目錄
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 或發(fā)送 SIGTERM 信號

注意事項

需要在Linux環(huán)境下編譯運行

確保有足夠的權(quán)限啟動配置的進程

根據(jù)實際需求修改進程配置

可執(zhí)行文件路徑必須是絕對路徑

建議在生產(chǎn)環(huán)境中添加更完善的錯誤處理和日志記錄

以上就是使用C++設(shè)計開發(fā)一個功能完善的多進程管理器的詳細內(nèi)容,更多關(guān)于C++多進程管理器的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 使用CMake構(gòu)建一個簡單的C++項目的實現(xiàn)

    使用CMake構(gòu)建一個簡單的C++項目的實現(xiàn)

    CMake是一個跨平臺的自動化構(gòu)建工具,可以用于構(gòu)建各種類型的項目,本文主要介紹了使用CMake構(gòu)建一個簡單的C++項目,具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • C語言繪制三角函數(shù)曲線

    C語言繪制三角函數(shù)曲線

    這篇文章主要為大家詳細介紹了C語言繪制三角函數(shù)曲線,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • C++ qt 使用jsoncpp json 讀寫操作

    C++ qt 使用jsoncpp json 讀寫操作

    JsonCpp是一個基于C++語言的開源庫,用于C++程序的Json數(shù)據(jù)的讀寫操作,本文重點給大家介紹C++ qt 使用jsoncpp json 讀寫操作,感興趣的朋友跟隨小編一起看看吧
    2021-11-11
  • C++利用Opencv實現(xiàn)多個圓形檢測

    C++利用Opencv實現(xiàn)多個圓形檢測

    霍夫圓檢測是opencv中用來檢測圓的重要算法,簡單的說,霍夫圓檢測就是對圖像中的弧線做切線,再在切點位置做切線的垂線,然后看這些垂線能交于一點的個數(shù),這個在方法中是自己設(shè)定的
    2022-08-08
  • 使用C/C++調(diào)用libcurl調(diào)試消息的方式

    使用C/C++調(diào)用libcurl調(diào)試消息的方式

    在使用 C/C++ 調(diào)用 libcurl 進行 HTTP 請求時,有時我們需要查看請求的/應(yīng)答消息的內(nèi)容(包括請求頭和請求體)以方便調(diào)試,libcurl 提供了多種方法來捕獲和輸出這些信息,本文介紹具體的使用方式,需要的朋友可以參考下
    2025-02-02
  • Ubuntu中使用VS Code與安裝C/C++插件的教程詳解

    Ubuntu中使用VS Code與安裝C/C++插件的教程詳解

    這篇文章主要介紹了Ubuntu中使用VS Code與安裝C/C++插件的教程詳解,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • Qt利用DOM類實現(xiàn)讀取xml文件

    Qt利用DOM類實現(xiàn)讀取xml文件

    Dom(Document Object Model,即文檔對象模型)能把XML文檔轉(zhuǎn)換成應(yīng)用程序可遍歷的樹形結(jié)構(gòu),這樣便可以隨機訪問其中的節(jié)點。本文將詳細講講實現(xiàn)的方法,需要的可以參考一下
    2022-06-06
  • C++實現(xiàn)教職工管理系統(tǒng)課程設(shè)計

    C++實現(xiàn)教職工管理系統(tǒng)課程設(shè)計

    這篇文章主要為大家詳細介紹了C++實現(xiàn)教職工管理系統(tǒng)課程設(shè)計,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 淺談C++對象組合

    淺談C++對象組合

    本文主要說明對象創(chuàng)建時構(gòu)造函數(shù)的執(zhí)行順序,對象成員的初始化順序;對象銷毀時析構(gòu)函數(shù)的執(zhí)行順序,對象成員的銷毀順序。
    2015-06-06
  • C++基于EasyX庫實現(xiàn)拼圖小游戲

    C++基于EasyX庫實現(xiàn)拼圖小游戲

    這篇文章主要為大家詳細介紹了C++基于EasyX庫實現(xiàn)拼圖小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07

最新評論

荔浦县| 定西市| 泸水县| 潮安县| 宝坻区| 宁国市| 合阳县| 专栏| 武邑县| 惠州市| 江津市| 盐亭县| 玉溪市| 武胜县| 达孜县| 清水河县| 山西省| 社旗县| 谷城县| 丰顺县| 塔城市| 电白县| 镇江市| 宜章县| 和林格尔县| 墨竹工卡县| 利川市| 乌拉特后旗| 浦江县| 永靖县| 福鼎市| 榆中县| 平凉市| 无为县| 乃东县| 府谷县| 平乡县| 元朗区| 康保县| 贵州省| 凤凰县|