你可以用你的拉姆达在另一个lambda这将需要数着“正在进行”任务的照顾,然后如果有太多正在进行的任务发布前等待。
例子:
#include <atomic>
#include <chrono>
#include <future>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
#include <boost/asio.hpp>
class ThreadPool {
using asio_worker = std::unique_ptr<boost::asio::io_service::work>;
boost::asio::io_service service;
asio_worker service_worker;
std::vector<std::thread> grp;
std::atomic<int> inProgress = 0;
std::mutex mtx;
std::condition_variable busy;
public:
ThreadPool(int threads) : service(), service_worker(new asio_worker::element_type(service)) {
for (int i = 0; i < threads; ++i) {
grp.emplace_back([this] { service.run(); });
}
}
template<typename F>
void enqueue(F && f) {
std::unique_lock<std::mutex> lock(mtx);
// limit queue depth = number of threads
while (inProgress >= grp.size()) {
busy.wait(lock);
}
inProgress++;
service.post([this, f = std::forward<F>(f)]{
try {
f();
}
catch (...) {
inProgress--;
busy.notify_one();
throw;
}
inProgress--;
busy.notify_one();
});
}
~ThreadPool() {
service_worker.reset();
for (auto& t : grp)
if (t.joinable())
t.join();
service.stop();
}
};
int main() {
std::unique_ptr<ThreadPool> pool(new ThreadPool(4));
for (int i = 1; i <= 20; ++i) {
pool->enqueue([i] {
std::string s("Hello from task ");
s += std::to_string(i) + "\n";
std::cout << s;
std::this_thread::sleep_for(std::chrono::seconds(1));
});
}
std::cout << "All tasks queued.\n";
pool.reset(); // wait for all tasks to complete
std::cout << "Done.\n";
}
输出:
Hello from task 3
Hello from task 4
Hello from task 2
Hello from task 1
Hello from task 5
Hello from task 7
Hello from task 6
Hello from task 8
Hello from task 9
Hello from task 10
Hello from task 11
Hello from task 12
Hello from task 13
Hello from task 14
Hello from task 15
Hello from task 16
Hello from task 17
Hello from task 18
All tasks queued.
Hello from task 19
Hello from task 20
Done.
问题不在于'io_service'在完成工作之前停止---我们知道删除'work'对象以使'io_service'正常停止。问题在于'io_service'允许累积太多的任务。我们希望以一种不涉及创建任务的线程轮询的方式来限制未分配的任务的数量,因此我们关于是否可以阻止“poll()”的问题。 – uckelman 2012-07-28 21:34:17