thread pool: simplify cleanup logic

This commit is contained in:
Adrien Béraud committed 2023-08-20 23:02:41 -04:00
1 parent 9e0ad9d926
commit 285105c8d1
2 files changed
+13 -26

No files matched your search

+12 -23
View File
@@ -49,7 +49,7 @@ ThreadPool::ThreadPool(unsigned minThreads, unsigned maxThreads)
{
threads_.reserve(maxThreads_);
if (minThreads_ != maxThreads_) {
threadDelayRatio_ = std::pow(2, 1.0 / (maxThreads_ - minThreads_));
threadDelayRatio_ = std::pow(3, 1.0 / (maxThreads_ - minThreads_));
}
}
@@ -122,14 +122,20 @@ void
ThreadPool::threadEnded(std::thread& thread)
{
std::lock_guard<std::mutex> l(lock_);
endedThreads_.emplace_back(thread);
tasks_.emplace([this]{
cleanupThreads();
tasks_.emplace([this,t=std::reference_wrapper<std::thread>(thread)]{
std::lock_guard<std::mutex> l(lock_);
for (auto it = threads_.begin(); it != threads_.end(); ++it) {
if (&*(*it) == &t.get()) {
t.get().join();
threads_.erase(it);
break;
}
}
});
// A thread expired, maybe after handling a one-time burst of tasks.
// If new threads start later, increase the expiration delay.
if (threadExpirationDelay > std::chrono::hours(168)) {
// If we reach 7 days, assume the thread pool is often used at max capacity
if (threadExpirationDelay > std::chrono::hours(24 * 7)) {
// If we reach 7 days, assume the thread is regularly used at full capacity
minThreads_ = std::min(minThreads_+1, maxThreads_);
} else {
threadExpirationDelay *= threadDelayRatio_;
@@ -137,23 +143,6 @@ ThreadPool::threadEnded(std::thread& thread)
cv_.notify_one();
}
void
ThreadPool::cleanupThreads()
{
std::lock_guard<std::mutex> l(lock_);
if (not endedThreads_.empty()) {
for (auto& thread : endedThreads_)
thread.get().join();
endedThreads_.clear();
for (auto it = threads_.begin(); it != threads_.end();) {
if (not (*it)->joinable())
it = threads_.erase(it);
else
++it;
}
}
}
void
ThreadPool::stop(bool wait)
{