You make a good point. I recently read a blog referencing a MITI study (Japan) stating the problems with software development and errors after shipping. Here's a link to the blog:
Explain why C is a failure for concurrent programming. Any pthreads library provides the necessary functionality for multi-core programming in linux for instance where each process can be forked cop-on-write with SMP. Moreover, concurrent programming on enterprise systems has been efficient for more than 10 years with little or no issues in C or C++ for that matter. If a generalization is going to be made, at least support the statement. Concurrent programming is less in the language as it is in the threading environment, message passing, and shared memory IPC features of a given OS/RTOS.
C source code, like most programming languages, has no way to express parallelism. It has no concept of time and is inherently serial, assuming that everything happens in sequence. That's not to say a compiler can't find some parallelism on its own. It can. Smart compilers can spot opportunities to unroll loops or perform parallel calculations that aren't dependant on one another, but that's all opportunistic. I can't tell the compiler to do this in my source code; it must find its own opportunities at compile time.
That's doesn't make C a bad language; it's just not something C's developers anticipated. There's no way to say in C "I want you to do this AND, while you're at it, do this other thing as well." There's no vocabulary for that. If you want to write a recipe for two cooks working in the same kitchen, you have to write two separate sets of directions and find some way to synchronize the two so they cooperate. With luck, they won't need to cooperate much. English, like C, has no elegant way to interleave the directions for two or more people simultaneously. And certainly no way to "load balance" their tasks. You have to anticipate (based on some foreknowledge or experience) that Chef A will take X amount of time to accomplish his given task while Chef B takes Y amount of time for his, and so on.
Biologically, we're wired to communicate serially. All human languages (AFAIK) are like this. Thus it's no surprise that programming languages are serial as well. It's only recently that we've had the need or the desire to program many tasks in parallel. It's generally been an ad hoc process of using serial programming running on serial (i.e., scalar) processors, with some inter-process communication thrown in. We're still a long way from true parallel programming that's well suited to multicore processors.
Small nit - Java and C# are two languages recently introduced that have caught on.
That said, I'm not sure a language around parallel programming will catch on. This is one of the challenges I have in my work - that of being too parallel/multicore-centric. We see a number of solutions (used that word because I know how much you like it) where the aspect of parallelism requires a large amount of baggage, be it large scale managed environments dedicated to the problem (ala Ct), or even a large number of API calls (OpenCL).
These are all well and good, but I would think there's value in an incremental approach that is bolted on top of existing languages. So OpenMP and future extensions to OpenMP for heterogeneous would be promising.