Skip to content

Instantly share code, notes, and snippets.

@pengdu
Last active August 8, 2023 11:43
Show Gist options
  • Save pengdu/c12042e43c3f05203769881e92ef1a43 to your computer and use it in GitHub Desktop.
Save pengdu/c12042e43c3f05203769881e92ef1a43 to your computer and use it in GitHub Desktop.
C++进程池 chatgpt

以下是一个简单的C++进程池的示例代码:

#include <iostream>
#include <vector>
#include <queue>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

class ProcessPool {
public:
    ProcessPool(size_t numProcesses) {
        for (size_t i = 0; i < numProcesses; ++i) {
            pid_t pid = fork();
            if (pid == -1) {
                std::cerr << "Failed to fork process" << std::endl;
                exit(1);
            } else if (pid == 0) {
                // Child process
                while (true) {
                    if (!tasks.empty()) {
                        std::function<void()> task;
                        {
                            std::lock_guard<std::mutex> lock(queueMutex);
                            task = std::move(tasks.front());
                            tasks.pop();
                        }
                        task();
                    }
                }
                exit(0);
            } else {
                // Parent process
                processIds.push_back(pid);
            }
        }
    }

    template <class F, class... Args>
    void enqueue(F&& f, Args&&... args) {
        {
            std::lock_guard<std::mutex> lock(queueMutex);
            tasks.emplace([=] { std::forward<F>(f)(std::forward<Args>(args)...); });
        }
    }

    ~ProcessPool() {
        for (pid_t pid : processIds) {
            kill(pid, SIGTERM);
        }
        for (pid_t pid : processIds) {
            waitpid(pid, nullptr, 0);
        }
    }

private:
    std::vector<pid_t> processIds;
    std::queue<std::function<void()>> tasks;
    std::mutex queueMutex;
};

void taskFunction(int taskId) {
    std::cout << "Task " << taskId << " is being executed by process " << getpid() << std::endl;
    sleep(1);
    std::cout << "Task " << taskId << " is done" << std::endl;
}

int main() {
    ProcessPool pool(4);

    for (int i = 0; i < 8; ++i) {
        pool.enqueue(taskFunction, i);
    }

    sleep(5);

    return 0;
}

在这个示例中,我们定义了一个ProcessPool类来实现进程池。在构造函数中,我们通过调用fork()创建了指定数量的子进程,并将其ID存储在processIds向量中。每个子进程都会无限循环地检查任务队列,如果队列不为空,则取出任务并执行。

enqueue函数用于向进程池中添加任务。它接受一个可调用的函数对象和参数,并将其包装成一个std::function对象放入任务队列中。

main函数中,我们创建了一个包含4个子进程的进程池pool。然后,我们使用enqueue函数将8个任务添加到进程池中。每个任务都会输出自己的编号以及执行任务的进程的编号,并在执行完毕后输出任务完成的消息。最后,我们让主进程休眠5秒钟,以便观察任务的执行情况。

这个实现有错误。。。哈哈哈

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment