linux

Linux环境下C++如何进行多进程管理

小樊
49
2025-10-23 09:42:54
栏目: 编程语言

在Linux环境下,C++可以通过多种方式实现多进程管理。以下是一些常用的方法:

1. 使用 fork() 系统调用

fork() 是创建新进程的最基本方法。它会在当前进程中创建一个子进程,子进程是父进程的副本。

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>

int main() {
    pid_t pid = fork();

    if (pid == -1) {
        // 错误处理
        std::cerr << "Fork failed" << std::endl;
        return 1;
    } else if (pid == 0) {
        // 子进程
        std::cout << "Child process, PID: " << getpid() << std::endl;
    } else {
        // 父进程
        std::cout << "Parent process, PID: " << getpid() << ", Child PID: " << pid << std::endl;
        wait(NULL); // 等待子进程结束
    }

    return 0;
}

2. 使用 exec() 系列函数

exec() 系列函数用于在当前进程中执行一个新的程序。通常与 fork() 结合使用。

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>

int main() {
    pid_t pid = fork();

    if (pid == -1) {
        std::cerr << "Fork failed" << std::endl;
        return 1;
    } else if (pid == 0) {
        // 子进程
        execl("/bin/ls", "ls", "-l", (char *)NULL);
        std::cerr << "Exec failed" << std::endl; // 如果 exec 失败,会执行到这里
        return 1;
    } else {
        // 父进程
        int status;
        waitpid(pid, &status, 0); // 等待特定子进程结束
        if (WIFEXITED(status)) {
            std::cout << "Child exited with status " << WEXITSTATUS(status) << std::endl;
        }
    }

    return 0;
}

3. 使用 system() 函数

system() 函数可以执行一个 shell 命令,它会创建一个新的 shell 进程来执行命令。

#include <cstdlib>

int main() {
    int status = system("ls -l");
    if (status == -1) {
        std::cerr << "System call failed" << std::endl;
        return 1;
    }
    return 0;
}

4. 使用 posix_spawn() 函数

posix_spawn() 是一个更现代的函数,用于创建新进程并执行一个程序。

#include <iostream>
#include <spawn.h>
#include <sys/wait.h>

int main() {
    pid_t pid;
    char *argv[] = {"ls", "-l", NULL};
    posix_spawn_file_actions_t actions;

    posix_spawn_file_actions_init(&actions);

    if (posix_spawn(&pid, argv[0], &actions, NULL, argv, environ) != 0) {
        std::cerr << "Posix spawn failed" << std::endl;
        return 1;
    }

    waitpid(pid, NULL, 0); // 等待子进程结束

    posix_spawn_file_actions_destroy(&actions);

    return 0;
}

5. 使用进程池

进程池是一种管理多个工作进程的技术,可以有效地处理大量短生命周期的任务。

#include <iostream>
#include <vector>
#include <thread>
#include <queue>
#include <functional>
#include <mutex>
#include <condition_variable>

class ThreadPool {
public:
    ThreadPool(size_t threads) : stop(false) {
        for (size_t i = 0; i < threads; ++i) {
            workers.emplace_back([this] {
                while (true) {
                    std::function<void()> task;
                    {
                        std::unique_lock<std::mutex> lock(this->queue_mutex);
                        this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
                        if (this->stop && this->tasks.empty()) {
                            return;
                        }
                        task = std::move(this->tasks.front());
                        this->tasks.pop();
                    }
                    task();
                }
            });
        }
    }

    template<class F, class... Args>
    void enqueue(F&& f, Args&&... args) {
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            if (stop) {
                throw std::runtime_error("enqueue on stopped ThreadPool");
            }
            tasks.emplace([f, args...] { f(args...); });
        }
        condition.notify_one();
    }

    ~ThreadPool() {
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            stop = true;
        }
        condition.notify_all();
        for (std::thread &worker : workers) {
            worker.join();
        }
    }

private:
    std::vector<std::thread> workers;
    std::queue<std::function<void()>> tasks;
    std::mutex queue_mutex;
    std::condition_variable condition;
    bool stop;
};

int main() {
    ThreadPool pool(4);

    for (int i = 0; i < 8; ++i) {
        pool.enqueue([i] {
            std::cout << "Task "<< i << " is running in thread " << std::this_thread::get_id() << std::endl;
        });
    }

    return 0;
}

这些方法各有优缺点,选择哪种方法取决于具体的应用场景和需求。

0
看了该问题的人还看了