Monday, April 11, 2011

Rules for finding / avoiding shared data in a multithreaded application

Hy,

as we all know, developing a multithreading application is a hard thing. Especially the point when and what to lock is not so obvious IMHO. Often I'm looking at a method / class and I must ask myself, if I share some data, which can be modified by multiple threads. And when I'm not sure it ends in a lock( ) over a whole code block.

So what I like to know: Do you have suggestions for patterns / rules etc. to identify shared data? Or techniques to ensure that your code is thread-safe.

E.g.:

  • Static methods shouldn't modify class fields. (Unless they lock the field.)
  • Reference type'd parameters of a method should not be passed "directly". Always pass a clone.

By the way:

Microsoft Research is working on CHESS. A tool for finding and reproducing Heisenbugs in concurrent programs. I hope this and PLINQ will make improve development of concurrent programs.

From stackoverflow
  • Wherever possible, make your types immutable to start with. Then there's no need to clone. If you need to "change" the contents of an object, make the method return a new object instead - just like String.Replace etc does.

    This is basically the functional programming style, and it's lovely. It's unfortunate that we don't (currently) have immutable collections built into the .NET framework, althoughthere are third party ones around, including one by our own JaredPar.

    danio : Sounds interesting. http://codebetter.com/blogs/patricksmacchia/archive/2008/01/13/immutable-types-understand-them-and-use-them.aspx may be useful to people who want to learn more.
    TomTom : +1 As always a very useful answer. Sounds very good to use immutable types. A "subquestion": var's (anonymous types) in C# are immutable, aren't they?
    Jon Skeet : @TomTom: Yes, the anonymous types themselves are immutable in C#. That's not necessarily the case in VB though (it depends on how the anonymous type is created).
    TomTom : @Jon: Thanks for the answers. I let the question on an not-answered state, to give others the opportunity to write something about it. But when nothing else comes in, I will give you the reputation points. Seems they are afraid when you already anserwed a question ;-P
  • Encapsulating data in a class is useful when making it thread safe. You get control over how the data is accessed, and you can make the class responsible for the synchronising instead of having code all over the application trying to synchronise properly.

    Also, you have somewhere to put a private variable that you can use as lock identifier, so that you can avoid using the data itself as identifier for the lock. By having a private variable dedicated as lock identifier you remove one possible source of deadlocks.

0 comments:

Post a Comment