C++ Logo

std-proposals

Advanced search

unlock_at_thread_exit()

From: Vinícius dos Santos Oliveira <vini.ipsmaker_at_[hidden]>
Date: Sat, 10 Jul 2021 11:23:16 -0300
C++'s threads library currently exposes the function
notify_all_at_thread_exit() to join detached threads through a
condition variable. Thus we can join on detached threads in the likes
of:

while (!ready) cv.wait(lk);

One scenario where cond-based join logic is more attractive than
thread::join() is to join multiple worker threads. Traditionally one
would:

std::vector<std::thread> workers;
for (/* ... */) workers.emplace_back(/* ... */);
// ...
for (auto& t: workers) t.join();

However when worker threads themselves can add even new threads to the
pool we have to constantly grow/shrink workers as they change.
Furthermore the variable workers would have to be protected through a
mutex. Condition variables make the implementation simpler and more
efficient:

std::size_t nworkers = 0;
// ...
std::unique_lock lk(nworkers_mtx);
while (nworkers > 0) workers_gone_cond.wait(lk);

Unfortunately the current featureset for C++ still adds some overhead
to this pattern. The worker threads will have to use code such as:

std::unique_lock lk(nworkers_mtx);
--nworkers;
std::notify_all_at_thread_exit(workers_gone_cond, std::move(lk);

This code will awake the waiting thread at every joined worker.
Ideally we should be able to write:

std::unique_lock lk(nworkers_mtx);
--nworkers;
if (nworkers == 0)
  std::notify_all_at_thread_exit(workers_gone_cond, std::move(lk);
else
  std::unlock_at_thread_exit(std::move(lk));

I think C++ should have std::unlock_at_thread_exit(). I have a
codebase affected by this issue as of now. My workaround is to use a
different dummy cond to avoid awaking the parent thread.


-- 
Vinícius dos Santos Oliveira
https://vinipsmaker.github.io/

Received on 2021-07-10 09:24:10