I know about the theoretical solution of taking locks always in a defined order, but I don't consider it a practical solution. If taking locks willy-nilly lets you scale to program size X, this might give you 2X or 3X, but that's not nearly large enough in practice.
& dandelany, the community has chipped in and answered for me. I endorse this subthread, at least, as I write this comment. :)
I've got multi threaded C++ in production right now, and it is because the code is small and avoids multiple locks that I have any faith in it. As a code base expands, in kloc and in time, this gets harder and harder to reason about.
danluu claims there's other reasons it's not good enough but I was never able to figure out what he meant. Exception safety maybe.