[cpp-threads] Proposing a layered Thread API

Ion Gaztañaga igaztanaga at gmail.com
Sun Sep 3 12:18:57 BST 2006


 > I also don't see why a reference count plus a copy will be expensive.
 > There is no significant space overhead to a reference count and no
 > additional allocations required and, unless someone is pathologically
 > making copies all over the place, there is little cost associated with
 > copying. Perhaps you could clarify where the reference count plus copy
 > overhead is.

I agree that if you return cheap objects, copy is not a big issue. If 
the returned object is a big object, then it can be. In C++03 returning 
a vector or a string by value is not a very good idea because it forces 
the creation of a temporary (supposing RVO is not applied) but in C++0x 
that's not the case. User functions that are fine when executed like 
function calls in C++0x because we count with move semantics:

std::string to_upper_case(const std::string &);

std::string s = ...

s = to_upper_case(s);

have an overhead when executed asynchronously because you need to do two 
copies, one when creating the return value, and another one each time a 
future requests the value.

//Parameter can be passed by move semantics, no extra allocation
future<std::string> f = thread_pool(bind(to_upper_case, std::move(s));

//The asynchronous function ends, and constructs the result

//The result is copied to s
s = f();

Apart from this, that can be negligible with common types, the fact that 
you can use future as many times as you want from the same thread, leads 
to the illusion that future is very similar to a synchronous value, 
which is not true, because:

-> Each time you call f(), you create a copy
-> Each time you call f(), you need to hold a mutex (copy constructor is 
not thread-safe, unless it's trivial or we explicitly say it with concepts)

The first case will be noticeable if we return heavy objects, the second 
reason will be noticeable when returning cheap objects. Obviously, we 
will have synchronization costs when launching the thread (example: 
passing the object function to the thread pool and picking a free 
thread) but the less synchronization we have, the better, IMHO.

Definitively I should implement both approaches and do some basic 
benchmarking, to really know the impact of the copy/reference-counting 
approach. I agree that having more concepts is not necessarily better 
and might confuse the user.

 > Hmm, given the frequent need to use quotes for clarification, I am
 > beginning to think that renaming "joiner" to "thread" was not as
 > practical an idea as it first appeared :-} The object type in question
 > is categorically not itself a thread and makes talking about threads
 > slightly more awkward. I am not wed to "joiner", but in discussion the
 > name "thread" actually seems less clear.

I really don't have anything against "joiner" because actually the 
object's main task is joining the OS thread, and the OS thread is 
detached when the object is destroyed. But in the meeting some argued 
that it was confusing for regular users and that following Boost's 
"thread" name was a better choice. A question of compromise, I guess.

Regards,

Ion



More information about the cpp-threads mailing list