I find it rather daring to use raw POSIX threads or similar, hoping that automated debugging tools operating at this abstraction level, such as Helgrind or TSAN, will pinpoint your bugs. The problem is that the state space of a thread-based program synchronizing with mutexes is too large to explore at a reasonable time. More about this: http://yosefk.com/blog/checkedthreads-bug-free-shared-memory... and http://yosefk.com/blog/making-data-races-manifest-themselves...
Which higher-level abstraction to use is a question and depends on the problem at hand; for throughput computing in C, Cilk is perhaps the best today (I guess you could call my own project checkedthreads a bit of a Cilk knock-off.) AFAIK, Rust developers are more interested in higher-level abstractions than Go developers (Go's built-in goroutines being on par with threads in terms of ability of automated debugging tools to flag bugs; perhaps there's work in Go on higher-level abstractions but the vibe I felt, perhaps mistakenly, is that these are non-problems, which I disagree with: http://yosefk.com/blog/parallelism-and-concurrency-need-diff...)