C++ 线程池 传递任务 enqueue
时间: 2024-09-07 18:04:17 浏览: 79
在C++中,线程池是一种常见的并发工具,用于管理和调度一组预创建的线程,以便高效地处理大量小任务。线程池通过提供一个队列(enqueue操作)将任务添加到线程组,而不是每次需要新线程就立即创建。当线程空闲时,它会从队列中取出任务并执行。
`enqueue`操作通常是一个模板函数,接受一个函数指针或Lambda表达式以及任何必要的参数,作为待执行的任务。例如,在C++11引入的`std::thread_pool`库(实际库可能会有所不同)中,enqueue可能看起来像这样:
```cpp
#include <ThreadPool>
using namespace std::this_thread;
// 创建一个线程池
ThreadPool pool(4); // 4个线程
// 定义一个函数或Lambda来表示任务
void worker_function(int task_id) {
// 任务的具体实现
}
// 使用enqueue提交任务
pool.enqueue(worker_function, 0); // 将0作为参数传递给worker_function
```
线程池的优点包括资源利用率高、避免频繁创建销毁线程导致的开销、易于管理等。然而,如果任务大小超过了线程的数量或者耗时过长,可能导致任务阻塞整个线程池,这时就需要考虑任务拆分或者优化线程池配置。
相关问题
C++ 线程池 传递多个参数 执行多线程
在C++中,如果你想要使用线程池来同时执行多个带参数的任务,你可以利用`std::packaged_task`配合`std::async`或者自定义`ThreadFunctionRunner`类。这里有一个简单示例,展示如何传递多个参数到线程池中的任务:
```cpp
#include <iostream>
#include <thread>
#include <vector>
#include <future>
#include <tuple>
// 创建一个接受两个参数的包装函数
template<typename Func, typename... Args>
std::packaged_task<decltype(Func(Args...))()> create_task(Func func, Args... args) {
return std::packaged_task<decltype(Func(Args...))()>([func = std::move(func), args = std::make_tuple(std::forward<Args>(args)...)]() mutable {
return func(args...);
});
}
class ThreadPool {
private:
std::vector<std::future<void>> futures;
const size_t max_threads;
public:
ThreadPool(size_t num_threads = std::thread::hardware_concurrency()) : max_threads(num_threads) {}
template<typename Func, typename... Args>
void enqueue(Func func, Args... args) {
if (futures.size() < max_threads) {
futures.push_back(create_task(func, args...).get_future());
execute();
} else {
std::cout << "ThreadPool is full, task will wait until slots are available." << std::endl;
}
}
void join_all() {
for (auto& future : futures) {
future.wait(); // 等待所有任务完成
}
futures.clear();
}
private:
void execute() {
if (!futures.empty()) {
auto task = futures.front().get_future();
futures.erase(futures.begin());
std::thread worker([task] {
task.wait(); // 当前线程执行任务
});
worker.join(); // 等待线程结束
}
}
};
int main() {
ThreadPool pool;
for (size_t i = 0; i < 5; ++i) {
pool.enqueue([](int a, int b) {
std::cout << "Task " << i << " executed with arguments (" << a << ", " << b << ")\n";
}, i, i * 10);
}
pool.join_all(); // 等待所有任务完成
return 0;
}
```
在这个示例中,`enqueue`方法接受一个函数`Func`和任意数量的参数`Args`,创建一个包装后的`packaged_task`,并将任务和未来结果存储在`futures`向量中。当线程池有足够的空间时,它会开始执行新的任务。
写一个c++ 线程池
好的,以下是一个简单的 C++ 线程池的实现:
```cpp
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
class ThreadPool {
public:
ThreadPool(size_t numThreads) {
for (size_t i = 0; i < numThreads; ++i) {
threads.emplace_back([this] {
while (true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(this->queueMutex);
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();
}
});
}
}
~ThreadPool() {
{
std::unique_lock<std::mutex> lock(queueMutex);
stop = true;
}
condition.notify_all();
for (std::thread& thread : threads) {
thread.join();
}
}
template<class F, class... Args>
void enqueue(F&& f, Args&&... args) {
auto task = std::make_shared<std::function<void()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
{
std::unique_lock<std::mutex> lock(queueMutex);
tasks.emplace([task] { (*task)(); });
}
condition.notify_one();
}
private:
std::vector<std::thread> threads;
std::queue<std::function<void()>> tasks;
std::mutex queueMutex;
std::condition_variable condition;
bool stop = false;
};
```
实现了一个简单的线程池,使用方法如下:
```cpp
void foo(int i) {
std::cout << "Hello from thread " << i << std::endl;
}
int main() {
ThreadPool pool(4);
for (int i = 0; i < 8; ++i) {
pool.enqueue(foo, i);
}
return 0;
}
```
这里创建了一个线程池,包含 4 个线程。然后循环了 8 次,将 foo 函数和循环变量 i 作为参数传递给线程池的 enqueue 函数,让线程池在空闲时执行这个函数。
阅读全文