Today I want to wrap up my concurrency series (finally). There are some more topics I'll be covering in the future (like the debugging concurrency issues I talked about yesterday :)), but I think I've said a reasonable amount about the issue (and frankly, I'd like to go on to other topics).
The most important thing to realize about concurrency is that while programming for concurrency is harder than programming in a single threaded environment, if you follow a relatively straightforward set of rules, it's not that much harder.
My series started off with a discussion about concurrency and what concurrency is.
I next introduced my principles of concurrent programming:
1: If your data is never accessed on more than one thread, then you don't have to worry about concurrency.
2: Critical sections can be your best friends (unless they're your worst enemy).
3: Know your lock order and never, ever violate it.
4: Don't call into other objects with locks being held, and make sure that you reference count all your objects.
5: Reference counting is hard if you're not really careful
Next, I talked about some of the reasons for introducing concurrency into your application as an introduction to discussing scalability
Finally, I discussed what it means to use concurrency as a mechanism of achieving application scalability, and I talked about some of the APIs that are useful when writing scalable applications.
And then I talked a bit about determining when you've got a CPU based scalability issue.
Finally, I spent two articles talking about hidden scalability issues - what happens when components out of your control have scalability issues, and what happens when your code collides with the design of the computer itself to cause scalability issues.
Those articles led to my final principle: If you're looking to concurrency to make your application scalable, you need to be really, really smart - there are bottlenecks in places you didn't think about.
Other resources I've come up with over the course of this series:
Eric Lippert had a great example of how you can get concurrency bottlenecks here: http://weblogs.asp.net/ericlippert/archive/2003/12/01/53411.aspx
There's an ancient, but awesome (and still relevant) article on MSDN written by John Vert here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndllpro/html/msdn_scalabil.asp.