在Linux环境下,C++可以通过多种方式实现多进程管理。以下是一些常用的方法:
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;
}
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;
}
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;
}
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;
}
进程池是一种管理多个工作进程的技术,可以有效地处理大量短生命周期的任务。
#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;
}
这些方法各有优缺点,选择哪种方法取决于具体的应用场景和需求。