Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2007-03-28 12:21:57


On Mar 27, 2007, at 9:49 PM, Peter Dimov wrote:

> There appears to be no need for a mutex in this prototype, unless I've
> missed something.
>
> Even if the actual implementation uses no n2178::handle, the above
> sketch
> might still be useful as an illustration of the semantics and thread
> safety
> that I have in mind. The omission of joinable() and
> cancel_requested() is
> intentional, the omission of the rest of the members is for brevity,
> although hardware_concurrency would probably be better off as a free
> function.

Thanks for the code. Correct me if I'm wrong, but this code keeps
state around after join and detach, and so might be problematic in the
vector<thread> use case shown earlier (where potentially many threads
can sit idle waiting to be recycled). Indeed, this implementation
appears to simply wrap const semantics in a non-const handle.

The "mixed thread safe" semantics I find interesting and a little
worrisome. Having some functionality thread safe and some not could
be seen as confusing. Looking again at the daemon spawner example:

std::thread launch;

...

vector<function<void()>> queue;
while (!queue.empty())
{
     launch = std::thread(queue.back());
     queue.pop_back();
     register(launch.get_id());
     if (something)
         break;
     launch.detach();
}
// work with undetached launch thread here

Except now "launch" is a global which other threads can access. Where
is it safe to race against this code?

A thread-safe detach() appears to have bought us little here since one
would have to race against the thread-unsafe move assign. And the
thread-safe detach() didn't come for free, we had to promise not to
get rid of resources in the vector<thread> use case.

Now we've got vector<thread> performance (good), but to do so we've
partially compromised mulit-parent simultaneous access (bad), and
we're potentially keeping resources around much longer than wanted
(bad).

Your suggestion is a compromise between the two designs (sole vs
shared ownership), but I'm not sure it is a good compromise.

I know we've got use cases which cry out for multi-parent access
(thread pool is likely to be one). But by far the most common use
cases appear to not need multi-parent access (http://www.boost.org/doc/html/threads/rationale.html#threads.rationale.non-copyable
). And thread pool (and other shared-ownership use cases) can be
layered onto the sole-ownership std::thread without compromise.

-Howard


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk