
On Mar 24, 2007, at 7:00 PM, Emil Dotchevski wrote:
If it prevents creating the "ideal" C++ interface (which, IMHO, is something along the lines of Howard's non-copyable thread class), then I'd consider it a disadvantage.
If someone can show that to be the case, I'd agree.
(Off-topic to this argument, but in response to your opinion, I am not sure I see the benefits of non-copyable thread handles. I am also concerned about the fact that in N2184 there is no thread handle for the current thread, which means that code that manipulates the current thread needs to be special case. To me, this looks a lot like C++ without a this pointer. Good design is all about selectively limiting unnecessary flexibility, but I am not sure that having copyable thread handles is unnecessary.)
I've been trying to sit on my hands as much as possible, because I really want to see independently formed ideas. But the hands slipped out and here I go. :-) 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. If fread() is currently cancelable (under pthreads) this means fread() can now throw an exception in C++. This might be upsetting to existing applications which assume the C fread() can't throw an exception. Don't read into this that I think pthreads and C+ + threads are inconsolable (I really don't know yet). Just read into it that cancellation is the critical connection that needs to be put under a microscope. I'm also not sure it is practical for some existing C platforms to unwind C++ exceptions through C stack frames. 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. 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). Current thread handle: This feeds from the sole ownership view vs the shared ownership view. 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. 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. Obviously there is some non-const functionality which "this thread" should have access to: disabling exceptions is the poster child. Even thread owners can't do this to their owned thread. 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). 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. :-) -Howard