"C++ Concurrency In Action: Practical Multithreading" by Anthony Williams is the first book to come out on multithreading and concurrency in the new C++. Williams is currently the primary developer and maintainer of the Boost.Thread library, a writer of many proposals for the C++11 thread library, and has for a while now provided (for a price) its first complete implementation (just::thread).
The Good: at long last C++ is thread-aware and this book shows the reader how to harness this newfound power. Williams starts out by introducing a number of thread-related concepts, like mutexes, condition variables, futures, promises, and atomics. This is an example-based book, so every new topic is fleshed out in code. Having introduced these concepts, the author goes on to apply them by designing lock-based concurrent data structures (a stack, a queue, a lookup table, and a linked list). Williams also shows how to use atomic operations to create lock-free stacks and queues. The book then examines more involved topics like thread pools (for which C++17 will probably have built-in support, though Williams doesn't venture a guess) and is rounded out by a welcome overview of how to identify deadlocks, livelocks, data races, and so on. Given the thematic breakup of the chapters, as well as the the wealth of the material collected in the Appendices, this book will come in very handy as a reference. More specifically, Appendix B has a nice comparison of the new C++ multithreading facilities with Java threads, POSIX threads, and the Boost Thread library. Even better is Appendix D, a very useful 120-page reference of the C++11 thread library, which is more usable in digital form (as part of the ebook or the online version of the just::thread documentation). This volume is not a tutorial on C++11, but Williams uses a number of its facilities repeatedly (e.g. deleted and lambda functions, as well as auto, rvalue references, move constructors, and variadic templates) and then gathers them all up in Appendix A, along with other features (like constexpr functions and std::tuple). Given the current scarcity of decent material on C++11, the repeated use of new constructs means that Williams' book can also function as a practical introduction of sorts to the new language standard. From a more pragmatic perspective, it's worth pointing out that you can find the complete source code for the book on the publisher's website. Importantly, everyone who buys a paper copy of the book may also download a free e-book version. As I've written before, it is to be hoped that other publishers will follow Manning's example.
The Bad: parts of the book feel more like a reference than a tutorial. In the early chapters, when Williams is introducing things like mutexes, futures, etc from the C++ thread library (along with a couple of boost constructs) it feels like he's faced with a number of C++ entities for which he has to provide a raison d'etre, so he goes over them one by one. Thus, from the get-go "C++ Concurrency In Action" seems to implicitly assume that the reader is already comfortable with conceptual questions relating to concurrency, e.g. after finishing this book a reader would not know what a semaphore is -- this should be contrasted with David Butenhof's classic "Programming with POSIX threads". In all fairness, Williams does discuss conceptual issues in chapter 8 (of 10), but what he includes there is too little too late (on a related note, section 8.3.1 on matrix multiplication is just begging for some example code, especially given the unconventional notation used in the figure). Even so, most of the multithreading material is actually explained: perhaps not always masterfully (e.g. "if your roommate occupies the bathroom for a long time, it can be frustrating if you need to use it"), but explained nonetheless. Things are different when it comes to the grasp of C++ Williams assumes of the reader: he uses std::result_of and std::make_shared hundreds of pages before explaining them, though that's still better than the case of std::mem_fn, which is simply never discussed (note that all of these are TR1-related). Ditto for std::distance. Sometimes he also borders on bad practice, in one case using no access specifier for the base class when inheriting and, in another case, showing a function defined in a friend declaration of a class -- both times without explicitly saying he's doing so. (I won't dwell on outright errors, like using Template Argument Deduction for a class template, p. 244, and then assuming that you can deduce the return type, pp. 246, 247, 249.) Yes, a "good working knowledge of C++ is assumed" by Williams, but it's worth pointing out that in "Effective C++" Scott Meyers devotes two sentences to explaining even what a default constructor is. Given the book's list price, a little more attention to detail and a few extra explanations would have been welcome.
In summary, this book suffers from pedagogical flaws, but it is a good reference. Equally important, this is the first book on the subject and it's written by a knowledgeable person so, unless someone like Hans Boehm decides to write a similar volume, Williams will probably have no serious competition. (Herb Sutter's "Effective Concurrency", if it comes out, will most likely belong to the "second book on the subject" genre.) Thus, I cannot in good conscience give this volume less than four stars.
Alex Gezerlis