以下是一个简单的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秒钟,以便观察任务的执行情况。
这个实现有错误。。。哈哈哈