From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2007-03-25 00:03:19
> Connection between pthreads and C++ threads: The critical connection > is cancellation. If you phthread_cancel a C++ thread, what happens? > If you thread::cancel() a pthreads thread, what happens? In the ideal > world everything would just work. I'm not convinced this is > practical.
We can say "oh well, whatever" and not standardize what happens when thread cancellation crosses the C/C++ language barrier; however this approach doesn't work where the rubber meets the road: at some point, someone will have to define these semantics. Without a standard, the implementation-defined semantics (as of today) vary from platform to platform; I do not see how this is helpful.
> Benefit of non-copyable (but movable) thread handle: It is all in how > you view: join, detach and cancel. If these are considered non-const > operations on the thread, then the sole-ownership model is much > simpler. I've got a thread, I own it, nobody else does, I can do non- > const things with it without fear of disturbing the universe. If > join, detach and cancel are const operations, (and if all other things > you can do through the handle are const) then under-the-cover > reference semantics are benign.
On Windows, you can have two joins on the same thread. Copyable thread handles can support this behavior directly. How does one achieve the same thing with N2184::thread semantics?
> This is quite analogous to reference counted strings: A reference > counted mutable string is complicated. If you modify one, you either > have to copy it so others sharing the data don't see the modification, > or you accept the fact that your string has reference semantics: > modify it here, and all other copies see what you've done. And OS > threads aren't copyable, so reference semantics for the handle are the > only option.> > A reference counted immutable string is quite simple. You never > modify it. The fact that it is shared is virtually undetectable (an > implementation detail).
Not only strings, sharing mutable objects of any type is complicated. Sometimes we define const interfaces which turn sharing into an implementation detail, and sometimes we deal with the complexities of mutable operations.
> Current thread handle: This feeds from the sole ownership view vs the > shared ownership view.
Yes, this is why I mentioned it. You can't have non-copyable semantics and allow the current thread to be able to take a self handle.
> In the sole-ownership view (value semantics), > there is only one owner of a thread. Only the owner can do non-const > things with it. Even the thread does not own itself unless it has > been passed its own sole-ownership handle. This simplifies (imho) > reasoning about non-const operations on the thread.
It simplifies the implementation and/or the documentation, and yes, simpler is better -- but only if the functionality that's taken away is not needed in practice. I don't think the boost::thread documentation claim that "it isn't needed very often" is acceptable. If even one valid use case exists that requires shared handles, then we either need shared handles or we need to show that the use case is in fact invalid.
> Otoh, if there is > a shared-ownership model (reference semantics), then one has copyable > thread handles and getting a copy of your own handle is very sensible.
I see things the other way around: if there are valid reasons for getting a copy of your own handle, then a shared-ownership model is sensible.
> thread::id is a practical exception to this model. It is common to be > able to identify threads, especially to see if the last thread that > executed *here* is *me* (recursive mutex prime example). So > thread::id is copyable, and you can get a copy of your own > thread::id. One can only do const-things with a thread::id, making it > harmless to share (can't tell the difference between reference > semantics and value semantics).
If I have shared thread handles, I can associate arbitrary data with a thread by a map<handle,data>. Independently, somebody else may have their own map<handle,data>. If I use thread::id in a similar way, how do I know when to dispose of the associated data? (if I remember correctly, if I have a thread::id, I can't check whether the corresponding thread has ended.)
> In general: thread manipulation of yourself is neither specifically > allowed nor disallowed in N2184. There's a single owner to every > thread. If you want to manipulate that thread, you have to be the > owner, even if that thread is yourself. No special case. Although > joining with yourself could be considered hazardous to your health and > frowned upon by your universe as a whole. :-)
i'm making a difference. Make every IM count for the cause of your choice. Join Now.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk