
Some background on myself to give context for this review: - Long-time user of boost in commercial C++ development - Making extensive use of threads and related constructs - Using home-brew future-like API for managing inter-thread communciations
What is your evaluation of the design(s)?
As others have noted, futures now appear in the draft C++ standard, and Anthony's API conforms closely to that (or, more correctly, the draft C++ standard appears to be based on Anthony's API). Unless I have some reason to think the draft C++ standard will completely change the proposed future API, I would tend to support Anthony's API. As Anthony has said in this thread, if conformance to the draft C++ standard future API is required for inclusion, he would help with that effort, for either API, which is fine with me. Design-wise, I prefer Anthony's API as it seems simpler to use; Braddock's API includes things of questionable value (to me). Specifically: - callbacks seem tricky to use/implement safely - future streams seem unnecessary at this point Braddock's API does try to address the notion of scheduling. One of the problems I've run into in using threads in C++ is that it is very important to treat threads as resources to be managed just like other limited OS resources. It generally isn't enough to say "oh, we'll just execute this on another thread"; this can often lead to a situation where you run out of threads, especially when thread execution can block. Scheduling, deciding when a thread can run (because futures that the execution is dependent on have become available), is a tricky notion in C++, because a thread blocked waiting for a future is taking up a limited resource, but without that thread waiting nothing will take action when the future does become available; Braddock's API tries to address this using callbacks. I don't think this is the correct approach. In C++ specifically, dealing well with threads requires care, by strictly limiting the number of threads being used and taking great care to avoid deadlocks and blocking among those threads; I don't think this is trivial. Thread-pools are probably the wrong general approach, though they may be appropriate in some contexts. It would be nice if some of the designs allowed for waiting on multiple futures; this would allow off-loading waiting for futures that looks hard to do in Anthony's API, but could possibly be done in Braddock's. Not sure if I'm explaining myself well here. In the product development I do, we often wind up dealing with situations where blocking a thread would cause lots of problems (specifically running out of threads), so there is typically a lot of additional complexity around ensuring that this doesn't happen.
What is your evaluation of the implementation(s)?
Anthony's implementation looks simple and straightforward; not much that I can say there. Braddock's is bigger, as goes with a bigger API. I'm glad that both APIs come with a test suite. As for Braddock's implementation, as I noted above, I'm not convinced of the need of the future stream. Implementation-wise, it seems complex. Based on Herb Sutter's recent forays into writing lock-free queues that perform well on modern multi-core hardware, I'm skeptical of the claim of "low lock contention" that the documentation makes. Note that I'm not against the concept of a future stream; I have implemented something similar in my application. Just don't think it needs to be part of the library.
What is your evaluation of the documentation?
Both seem complete. Overall I prefer Anthony's for succinctness, but it is a simpler API as well, which helps.
What is your evaluation of the potential usefulness of the library(s)?
As I said, I've implemented my own future-like API; having one available in boost would have been nice. There are many contexts that I would like to have one, every day :) Many jobs ago, I was introduced to futures (can't recall exactly; either through some beta version of Metrowerk's Powerplant library or on some MacHack CD, though I suspect the former), and have only started to see the concept pop up again in the last couple years. I'm pretty happy that they look to be coming into the C++ standard.
Did you try to use the library? With what compiler(s)? Did you have any problems?
Have not tried to use either.
How much effort did you put into your evaluation(s)? A glance? A quick reading? In-depth study?
Somewhere in between...
Are you knowledgeable about the problem domain?
I'd like to think so, but I keep learning more and realizing that I don't know as much as I think I do... Having said that, my current thinking is that using threads effectively in C++ is difficult, and a lot of the reason for this is the programming model itself. I suspect that effective use of multiple processors/cores could be done better in interpreted languages (my favourite model probably being something like Rob Pike's Newsqueak). If starting a new C++ project today, assuming I was dealing with a high-performance, mission-critical app, I would be probably be structuring code with threading in mind, the goal being to keep a small number of threads busy with none of those threads blocking, with waiting (I/O, asynchronous waits, etc) happening on a small number of additional threads. I'd probably avoid using thread pools entirely, based on experience.
Do you think the libraries should be accepted into Boost as-is or should they be merged?
As discussed, now that there appears to be a proposal in the draft standard, I would expect boost to at least have a matching API. As Vincente noted, it strikes me as odd that C++0x already has an proposal for the API in the draft and we're trying to decide what will make it into boost. The only reason I can see for putting a future library into boost at this point is to gain experience with the API to provide feedback for the C++ standard, until C++0x is defined and available in popular compilers. Additional things (e.g., future streams, callbacks) could be added as new boost extensions to C++0x API, but they should then be re-worked to fit that API... IMHO... Cheers Oliver Seiler