June 2009 C++ Standards Committee Mailing - New Working Draft and Concurrency Papers
Wednesday, 24 June 2009
The June 2009 mailing for the C++ Standards Committee was published today. This is the pre-meeting mailing for the upcoming committee meeting. Not only does it include the current C++0x working draft, but there are 39 other papers, of which 6 are concurrency related.
Concurrency-related papers
- N2880: C++ object lifetime interactions with the threads API
- This is a repeat of the same paper from the May 2009 mailing. It is referenced by several of the other concurrency papers. 
- N2888: Moving Futures - Proposed Wording for UK comments 335, 336, 337 and 338
- This is the first of my papers in this mailing. The current working draft restricts - std::unique_futureto be- MoveConstructible, but not- MoveAssignable. It also restricts- std::shared_futurein a similar way, by making it- CopyConstructible, but not- CopyAssignable. This severely limits the potential use of such futures, so the UK panel filed comments on CD1 such as UK comment 335 which requested relaxation of these unnecessary restrictions. This paper to provide a detailed rationale for these changes, along with proposed wording.
- N2889: An Asynchronous Call for C++
- This is the first of two papers in the mailing that proposes a - std::async()function for starting a task possibly asynchronously and returning a future for the result from that task. This addresses a need identified by UK comment 329 on CD1 for a simple way of starting a task with a return value asynchronously.
- N2901: A simple async()
- This is the second of the papers in the mailing that proposes a - std::async()function for starting a task possibly asynchronously and returning a future for the result from that task.- The primary difference between the papers is the type of the returned future. N2889 proposes a new type of future ( - joining_future), whereas N2901 proposes using- std::unique_future. There are also a few semantic differences surrounding whether tasks that run asynchronously aways do so on a new thread, or whether they may run on a thread that is reused for multiple tasks. Both papers provide a means for the caller to specify synchronous execution of tasks, or to allow the implementation to decide between synchronous execution and asynchronous execution on a case-by-case basis. N2901 also explicitly relies on the use of lambda functions or- std::bindto bind parameters to a call, whereas N2889 supports specifying function arguments as additional parameters, as per the- std::threadconstructor (see my introduction to starting threads with arguments in C++0x).- Personally, I prefer the use of - std::unique_futureproposed in N2901, but I rather like the argument-passing semantics of N2889. I also think that the- thread_localissues can be addressed by my proposal for that (N2907, see below). A final concern that I have is that calling the task inside- future::get()can yield surprising behaviour, as futures can be passed across threads, so this may end up being called on another thread altogether. For synchronous execution, I would prefer invoking the task inside the- std::asynccall itself, but delaying it to the- get()does allow for work-stealing thread pools.
- N2907: Managing the lifetime of thread_local variables with contexts
- This is the second of my papers in this mailing. It proposes a potential solution to the lifetime-of- - thread_local-variables issues from N2880 discussed in last month's blog post.- The idea is that you manage the lifetime of - thread_localvariables by constructing an instance of a new class- std::thread_local_context. When the- std::thread_local_contextinstance is destroyed, all- thread_localvariables created in that context are also destroyed. You can then construct a subsequent instance of- std::thread_local_context, and create new- thread_localinstances in that new context. This means that you can reuse a thread for multiple unrelated tasks, without "spilling"- thread_localvariables from an earlier task into later tasks. It can also be used with a- std::async()function to ensure that the- thread_localvariables are destroyed before the associated future is made ready.
- N2917: N2880 Distilled, and a New Issue With Function Statics
- This is Herb Sutter's take on the issues from N2880. He starts with a general discussion of the issue with detached threads and static destruction of globals, and then continues with a discussion of the issues surrounding the destruction of function-scoped - thread_localvariables. In particular, Herb focuses on something he calls Function- thread_localstatics poisoning- thread_localdestructors — if the destructor of a- thread_localobject- xcalls a function that itself uses a function-scope- thread_local- y, then the destructor of- ymight already have been called, resulting in undefined behaviour.- I found Herb's coverage of the issues surrounding detached threads dismissive of the idea that people could correctly write manual synchronization (e.g. using a - std::condition_variableor a- std::unique_future), even though this is common practice amongst those using POSIX threads (for example, in David Butenhof's Programming with POSIX Threads, he says "pthread_join is a convenience, not a rule", and describes examples using detached threads and condition variables to signal when the thread is done). I can see many possibilities for such usage, so as a consequence, I am personally in favour of his "solution" 1D: leave things as they are with regard to detached threads — it is already undefined behaviour to access something after its destruction.- However, the issue Herb raises with regard to order of destruction for - thread_localvariables is important, and not something that my- std::thread_local_contextproposal addresses. As Herb points out, the problem does exist with regard to function-local- staticvariables already —- thread_localjust amplifies the problem. I am inclined to go with what POSIX threads does, and what- boost::thread_specific_ptrdoes: make them "phoenix" variables that are re-initialized when accessed after destruction, and are thus added back onto the destructor list. This is Herb's solution 2B.
Other papers
Now that CD1 is out, and the committee is trying to get things pinned down for CD2, Concepts are getting a lot of discussion. There are therefore several papers on Concepts in the mailing. There are also papers on automatically defining move constructors, revised wording for lambdas, a proposal for unifying the function syntax, and several others. Check out the full list of papers for details.
Your comments
Do you have any comments on the papers (especially the concurrency
ones, but if you have any comments on the others I'd like to know
too)? Which std::async proposal do you prefer, or do you
like aspects of both or neither? Do you think that
thread_local_context objects combined with resurrecting
thread_local objects on post-destruction access solves
the thread_local issues?
Let me know by posting a comment.
Posted by Anthony Williams
[/  cplusplus /] permanent link
  Tags:  C++0x,  C++,  standards,  concurrency 
   Stumble It!  | Submit to Reddit
 | Submit to Reddit  | Submit to DZone
 | Submit to DZone 
If you liked this post, why not subscribe to the RSS feed  or Follow me on Twitter? You can also subscribe to this blog by email using the form on the left.
 or Follow me on Twitter? You can also subscribe to this blog by email using the form on the left.
Design and Content Copyright © 2005-2025 Just Software Solutions Ltd. All rights reserved. | Privacy Policy
No Comments