They were exaggerating of course -- and they were like gods, they fixed hundreds of sync bugs in C code, mixed with assembly for like 15 embedded platforms.
I am not such a hardcore programmer like them to this day even though I am almost 40 but the mutex/condition_var combo has bitten me many, many times. Spurious wakes, for example: not all platforms do them right (side note: I realise these may remain a forever fact of life and be a key to having preemptive scheduling like in the BEAM VM [Erlang/Elixir]). A lot of defensive coding is needed. And that's only one example out of dozens.
IMO you are just used to it. If you code in Erlang/Elixir on very parallel-friendly projects I am pretty sure you'll never go back to the pthreads model!
It's just the conclusion of the group of programmers to whom I philosophically belong (basically people who ran away screaming from C/C++ after working 2 to 10 years with them) that this stuff looks deceptively easy and it works quite well in many cases... until the projects gets big, many people get involved and bugs start to creep in. In such conditions, immutability + actor model have so far proven to be much more people-friendly paradigms that make introducing certain class of bugs much harder.
Sure thing, I have just stated my personal opinion, not looking for anyone to agree. To each their own. Everything has a price, immutability/actor included. The rest is all about the trade-offs one is willing to make
I am looking forward to see if the Rust community will manage to make a statically-typed BEAM-like runtime with much stronger performance characteristics. That would be amazing.
Quite frankly most of the multithreading things an synchronization is quite simple and does not bother me except some rare cases (dealing with DirectShow for example). If some languages fail to support real world constructs directly it is the problem of their designers and users. All this stuff about horrible, horrible manual memory management and awful synchronization issues is overblown I think.