C# Multi-Threading - Locking - c#

I was a bit confused on the concept of locking in some scenarios. Let me explain, suppose I have the following:
private readonly MyClass myObj;
private void Go(object state)
{
// call an instance member of myObj, but does it need to be locked?
myObj.SomeMethod(state);
}
So the question is does myObj need to be locked when calling SomeMethod? It is read-only, however since multiple threads can call the instance method SomeMethod of myObj with varying states will this not cause issues??
Thanks.

The variable is readonly, but the object may be mutable or immutable - and even that doesn't really tell you whether or not it can be used safely from multiple threads.
In other words, it depends on the implementation of MyClass, and whether you expect Go to be called from multiple threads referring to the same MyClass instance. (These days I tend to write classes not to be thread safe, but typically each thread gets its own set of objects to play with - so I'd probably have an instance of the class containing Go, and an instance of MyClass, but know that other threads shouldn't be using the same instances.)

It depends, if SomeMethod is a thread safe method then you don't need locking. Otherwise you may need to use lock.

It's hard to say for certain without more information on what you mean by "varying states", but in general, if a method is only reading from fields that you know won't be changed on other threads, you should be fine without a lock.
If you're only relying on readonly, though, then that's not good enough, since the object itself may be changing during calls from different threads.

Related

What Makes a Method Thread-safe? What are the rules?

Are there overall rules/guidelines for what makes a method thread-safe? I understand that there are probably a million one-off situations, but what about in general? Is it this simple?
If a method only accesses local variables, it's thread safe.
Is that it? Does that apply for static methods as well?
One answer, provided by #Cybis, was:
Local variables cannot be shared among threads because each thread gets its own stack.
Is that the case for static methods as well?
If a method is passed a reference object, does that break thread safety? I have done some research, and there is a lot out there about certain cases, but I was hoping to be able to define, by using just a few rules, guidelines to follow to make sure a method is thread safe.
So, I guess my ultimate question is: "Is there a short list of rules that define a thread-safe method? If so, what are they?"
EDIT
A lot of good points have been made here. I think the real answer to this question is: "There are no simple rules to ensure thread safety." Cool. Fine. But in general I think the accepted answer provides a good, short summary. There are always exceptions. So be it. I can live with that.
If a method (instance or static) only references variables scoped within that method then it is thread safe because each thread has its own stack:
In this instance, multiple threads could call ThreadSafeMethod concurrently without issue.
public class Thing
{
public int ThreadSafeMethod(string parameter1)
{
int number; // each thread will have its own variable for number.
number = parameter1.Length;
return number;
}
}
This is also true if the method calls other class method which only reference locally scoped variables:
public class Thing
{
public int ThreadSafeMethod(string parameter1)
{
int number;
number = this.GetLength(parameter1);
return number;
}
private int GetLength(string value)
{
int length = value.Length;
return length;
}
}
If a method accesses any (object state) properties or fields (instance or static) then you need to use locks to ensure that the values are not modified by a different thread:
public class Thing
{
private string someValue; // all threads will read and write to this same field value
public int NonThreadSafeMethod(string parameter1)
{
this.someValue = parameter1;
int number;
// Since access to someValue is not synchronised by the class, a separate thread
// could have changed its value between this thread setting its value at the start
// of the method and this line reading its value.
number = this.someValue.Length;
return number;
}
}
You should be aware that any parameters passed in to the method which are not either a struct or immutable could be mutated by another thread outside the scope of the method.
To ensure proper concurrency you need to use locking.
for further information see lock statement C# reference and ReadWriterLockSlim.
lock is mostly useful for providing one at a time functionality,
ReadWriterLockSlim is useful if you need multiple readers and single writers.
If a method only accesses local variables, it's thread safe. Is that it?
Absolultely not. You can write a program with only a single local variable accessed from a single thread that is nevertheless not threadsafe:
https://stackoverflow.com/a/8883117/88656
Does that apply for static methods as well?
Absolutely not.
One answer, provided by #Cybis, was: "Local variables cannot be shared among threads because each thread gets its own stack."
Absolutely not. The distinguishing characteristic of a local variable is that it is only visible from within the local scope, not that it is allocated on the temporary pool. It is perfectly legal and possible to access the same local variable from two different threads. You can do so by using anonymous methods, lambdas, iterator blocks or async methods.
Is that the case for static methods as well?
Absolutely not.
If a method is passed a reference object, does that break thread safety?
Maybe.
I've done some research, and there is a lot out there about certain cases, but I was hoping to be able to define, by using just a few rules, guidelines to follow to make sure a method is thread safe.
You are going to have to learn to live with disappointment. This is a very difficult subject.
So, I guess my ultimate question is: "Is there a short list of rules that define a thread-safe method?
Nope. As you saw from my example earlier an empty method can be non-thread-safe. You might as well ask "is there a short list of rules that ensures a method is correct". No, there is not. Thread safety is nothing more than an extremely complicated kind of correctness.
Moreover, the fact that you are asking the question indicates your fundamental misunderstanding about thread safety. Thread safety is a global, not a local property of a program. The reason why it is so hard to get right is because you must have a complete knowledge of the threading behaviour of the entire program in order to ensure its safety.
Again, look at my example: every method is trivial. It is the way that the methods interact with each other at a "global" level that makes the program deadlock. You can't look at every method and check it off as "safe" and then expect that the whole program is safe, any more than you can conclude that because your house is made of 100% non-hollow bricks that the house is also non-hollow. The hollowness of a house is a global property of the whole thing, not an aggregate of the properties of its parts.
There is no hard and fast rule.
Here are some rules to make code thread safe in .NET and why these are not good rules:
Function and all functions it calls must be pure (no side effects) and use local variables. Although this will make your code thread-safe, there is also very little amount of interesting things you can do with this restriction in .NET.
Every function that operates on a common object must lock on a common thing. All locks must be done in same order. This will make the code thread safe, but it will be incredibly slow, and you might as well not use multiple threads.
...
There is no rule that makes the code thread safe, the only thing you can do is make sure that your code will work no matter how many times is it being actively executed, each thread can be interrupted at any point, with each thread being in its own state/location, and this for each function (static or otherwise) that is accessing common objects.
It must be synchronized, using an object lock, stateless, or immutable.
link: http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html

can there be concurrency issues when using C# class with only static methods and no variables?

Have I understood correctly that all threads have copy of method's variables in their own stack so there won't be problems when a static method is called from different threads?
Yes and no. If the parameters are value types, then yes they have their own copies. Or if the reference type is immutable, then it can't be altered and you have no issues. However, if the parameters are mutable reference types, then there are still possible thread safety issues to consider with the arguments being passed in.
Does that make sense? If you pass a reference type as an argument, it's reference is passed "by value" so it's a new reference that refers back to the old object. Thus you could have two different threads potentially altering the same object in a non-thread-safe way.
If each of those instances are created and used only in the thread using them, then chances are low that you'd get bit, but I just wanted to emphasize that just because you're using static methods with only locals/parameters is not a guarantee of thread-safety (same with instance of course as noted by Chris).
Have I understood correctly that all threads have copy of method's variables in their own stack so there won't be problems when a static method is called from different threads?
No.
First off, it is false that "all threads have a copy of the method's local variables in their own stack." A local variable is only generated on the stack when it has a short lifetime; local variables may have arbitrarily long lifetimes if they are (1) closed-over outer variables, (2) declared in an iterator block, or (3) declared in an async method.
In all of those cases a local variable created by an activation of a method on one thread can later be mutated by multiple threads. Doing so is not threadsafe.
Second, there are plenty of possible problems when calling static methods from different threads. The fact that local variables are sometimes allocated on the stack does not magically make access to shared memory by static methods suddenly correct.
can there be concurrency issues when using C# class with only static methods and no variables?
I assume you mean "no static variables" and not "no local variables".
Absolutely there can be. For example, here's a program with no static variables, no non-static methods, no objects created apart from the second thread, and a single local variable to hold a reference to that thread. None of the methods other than the cctor actually do anything at all. This program deadlocks. You cannot assume that just because your program is dead simple that it contains no threading bugs!
Exercise to the reader: describe why this program that appears to contain no locks actually deadlocks.
class MyClass
{
static MyClass()
{
// Let's run the initialization on another thread!
var thread = new System.Threading.Thread(Initialize);
thread.Start();
thread.Join();
}
static void Initialize()
{ /* TODO: Add initialization code */ }
static void Main()
{ }
}
It sounds like you are looking for some magical way of knowing that your program has no threading issues. There is no such magical way of knowing that, short of making it single-threaded. You're going to have to analyze your use of threads and shared data structures.
There is no such guarantee unless all of the variables are immutable reference types or value types.
If the variables are mutable reference types, proper synchronization needs to be performed.
EDIT: Mutable variables only need to be synchronized if they are shared between threads- locally declared mutables that are not exposed outside of the method need not be synchronized.
Yes, unless methods use only local scope variable and no any gloval variable, so there is no any way any of that methods can impact on the state of any object, if this is true, you have no problems to use it in multithreading. I would say, that even , in this conditions, static they or not, is not relevant.
If they are variables local to the method then yes, you have nothing to worry about. Just make sure you are not passing parameters by reference or accessing global variables and changing them in different threads. Then you will be in trouble.
static methods can refer to data in static fields -- either in their class or outside of it -- which may not be thread safe.
So ultimately the answer to your question is "no", because there may be problems, although usually there won't be.
Two threads should still be able to operate on the same object either by the object being passed in to methods on different threads as parameters, or if an object can be accessed globally via Singleton or the like all bets are off.
Mark
As an addendum to the answers about why static methods are not necessarily thread-safe, it's worth considering why they might be, and why they often are.
The first reason why they might be is, I think, the sort of case you were thinking of:
public static int Max(int x, int y)
{
return x > y ? x : y;
}
This pure function is thread-safe because there is no way for it to affect code on any other thread, the locals x and y remain local to the thead they are on, not being stored in a shared location, captured in a delegate, or otherwise leaving the purely local context.
It's always worth noting, that combinations of thread-safe operations can be non thread-safe (e.g. doing a thread-safe read of whether a concurrent dictionary has a key followed by a thread-safe read of the value for that key, is not thread-safe as state can change between those two thread-safe operations). Static members tend not to be members that can be combined in such non thread-safe ways in order to avoid this.
A static method may also guarantee it's own thread-safety:
public object GetCachedEntity(string key)
{
object ret; //local and remains so.
lock(_cache) //same lock used on every operation that deals with _cache;
return _cache.TryGetValue(key, out ret) ? ret : null;
}
OR:
public object GetCachedEntity(string key)
{
object ret;
return _cache.TryGetValue(key, out ret) ? ret : null; //_cache is known to be thread-safe in itself!
}
Of course here this is no different than an instance member which protects itself against corruption from other threads (by co-operating with all other code that deals with the objects they share).
Notably though, it is very common for static members to be thread-safe, and instance members to not be thread-safe. Almost every static member of the FCL guarantees thread-safety in the documentation, and almost every instance member does not barring some classes specifically designed for concurrent use (even in some cases where the instance member actually is thread-safe).
The reasons are two-fold:
The sort of operations most commonly useful for static members are either pure functions (most of the static members of the Math class, for example) or read static read-only variables which will not be changed by other threads.
It's very hard to bring your own synchronisation to a third-party's static members.
The second point is important. If I have an object whose instance members are not thread-safe, then assuming that calls do not affect non-thread-safe data shared between different instances (possible, but almost certainly a bad design), then if I want to share it between threads, I can provide my own locking to do so.
If however, I am dealing with static members that are not thread-safe, it is much harder for me to do this. Indeed, considering that I may be racing not just with my own code, but with code from other parties, it may be impossible. This would make any such public static member next to useless.
Ironically, the reason that static members tend to be thread-safe is not that it's easier to make them so (though that does cover the pure functions), but that it's harder to! So hard in-fact that the author of the code has to do it for the user, because the user won't be able to themselves.

Question about lock objects and sub classes

So, I have a base class which has a private locking object like so:
class A
{
private object mLock = new object();
public virtual void myMethod()
{
lock(mLock)
{
// CS
}
}
}
This locking object is used for most of A's operations... because they need to be thread safe.
Now, lets say I inherit from A like so:
class B : public A
{
public override void myMethod()
{
lock(???)
{
// CS of mymethod here
// Call base (thread safe alread)
base.myMethod();
}
}
}
What is the convention for making B thread safe? Should B also have a private locking object like A does? What if I need to call the base method like above?
I guess I'm just curious what the convention is for making subclasses thread safe when the base class is already thread safe. Thanks!
Edit: Some are asking what I mean by "thread safe"... I'll clarify by adding that I'm trying to achieve thread safety through mutual exclusion... Only one thread at a time should be executing code which may alter the state of the object.
You would potentially expose the lock used by A:
protected object SyncLock { get { return mLock; } }
If B had its own lock object, you could easily end up with:
Different locks being used, potentially leading to race conditions. (It may be fine - if the operations occurring while holding lock B are orthogonal to those occurring while holding lock A, you may just get away with it.)
Locks being taken out recursively in different orders, leading to deadlocks. (Again, the orthogonality argument applies.)
As locks are recursive in .NET (for better or worse), if your override locks on the same object as A's implementation, it's fine to call base.myMethod and recursively acquire/release the lock.
Having said all of this, I'm keen on making most classes non-thread safe or immutable (only classes which are about threading need threading knowledge) and most classes don't need to be designed for inheritance IMO.
It depends really. If your subclass is only using the safe methods from your base class and doesn't add any extra unsafe state, than you don't have to do anything (preferred). If it add some extra state which is not correlated with the state of the base class, then you can create a separate lock object in the subclass and use that. If, on the other hand, you need to make sure that the new state and the state from the base class are changed in some sort "transactional" way, then I would make the lock object in the base class protected and use that.
There's not really enough information to answer your question, but first things first.
Just using lock blocks does not make your code thread-safe.
All you're doing in A is making it impossible for more than one thread at a time to call any function whose body you enclose in the lock(mLock). Thread safety is a broad term, and preventing concurrent calls is just one aspect (and isn't always what you want or need). If that is what you need, then you've obviously taken the right approach. Just be sure about it.
Second, what you need to expose to your subclass is not evident from the code above. You have three scenarios:
B might call protected (or internal if it's in the same assembly as A) functions on A that are not enclosed in the lock(mLock) blocks
B will only call functions on A that are enclosed in the lock(mLock) blocks and doesn't provide any operations of its own that require you to prevent concurrent calls
B will only call functions on A that are enclosed in the lock(mLock) blocks and also provides operations of its own that require you to prevent concurrent calls.
Which really boils down into two unrelated questions:
Will B interact with A in a way that needs to be protected (in other words, in a way that isn't already protected)?
Will B expose functionality that needs to be protected, and, if so, should they use the same locking object?
If 1) is true of 2) is true and they should use the same locking object, then you'll need to expose your locking object via a protected property and use that in all of your locks (I would suggest using it within A as well for readability).
If neither is true, then don't worry about it. If 2) is true but they don't need to use the same locking object (in other words, it would be acceptable to have concurrent calls to A and B), then don't worry about exposing the locking object. Remember that any calls that B makes into a function on A that's been protected by the lock(mLock) is going to lock on that object anyway, regardless of any outer locks.
What do you mean by "thread safe"? If this includes any ideas about reentrancy -- the idea that a method can only see the object in a good state, so only one method can be running at once -- then locking around methods may not do what you expect. For example, if your object ever calls out to another object in any way (an event?), and that object calls back in to the original object, the inner call will see the object in a "bad" state.
For this reason, when you're locking the whole object like this, you have to be careful about the code that runs inside the lock: "bad" code running inside the lock can compromise the correctness of your code.
Since subclassing introduces code that's outside the control of the original object, it's often seen as a dangerous way to work with self-locking classes like this, so one popular convention is "don't do it."
If, given the possible problems, you still want to take this route, then making the lockable object protected rather than private will allow you to include subclass operations inside the same base-class lock.
I thought the appropriate thing to do here is use lock(this), instead of creating an instance of another object just for locking. That should work for both cases.

Thread safety across shared instances (C#)

I use a factory pattern to create a custom object which is loaded from a cache if possible.
There are no static members or functions on the custom object.
Assuming 2 threads call the factory and are both returned references to the same object from the cache. (i.e. No new operator, in ref to answer below, object returned from a collection)
If I want to modify a private instance member on inside the class:
a) Shoulb I lock it first?
b) Will the change be reflected in both threads?
I assume yes for both questions, but at the same time it feels like the threads have different instances of the class.
Have I must something fundamental here? Why do I feel like I have?
===============
Following the first few answers I have confirmed what I thought, thanks.
I guess what I really want to know is, if the objects are pretty much only read-only, i.e. after being created they only have one instance member that can change, do I need to do any locks when reading properties that are not affected by that one changeable instance member?
Again I assume no, but I have to come to value the second-opinion of the collective StackOverflow brains trust :)
Reading and writing of most primitive types, string and object references is atomic (everything except non-volatile longs and doubles). This means locks are not necessary if you are simply reading or writing a field or other variable in isolation. So, if you ever see code like this (and I guaranteee you will), you can happily strip out the unnecessary and costly locking:
public SomeClass SomeProperty
{
get
{
lock (someLock)
{
return someField;
}
}
set
{
lock (someLock)
{
someField = value;
}
}
}
If, however, you want to change the value, increasing it by one for example, or if you want to read multiple, related variables then you need to lock if you want sensible results.
It is also worth noting that the Hashtable and Dictionary support mulitple concurrent readers without the need for any kind of locking.
You are assuming that the threads have different instances of the object, which is incorrect. The threads are pointing to the same object; therefore, you have to synchronize access to any members that might be accessed by multiple threads, whether it be through property accesses, method calls, etc, etc.
It should be the same object, and the answer to your questions is YES, YES.
How do you check that there are 2 instances?
Yes, you should lock before setting the private member. This will be reflected in both threads (since they're the same object).
However, you may want to take some time to consider how to handle the locks and threading.
If your factory is creating the object and adding it to the collection, it will need a lock of some form around the routine to create the object. Otherwise, it's possible that the two threads could ask for the object at the same time, before it was created, and create 2 instances.
Also, I wouldn't recommend setting the private member directly - it would be a good idea to have a single object inside of the returned class instance used just for locking, and use some form of accessor (method or property) that locks on that synchronization object and then sets the field.
As for not "trusting" that its two instances - you can always just do something to check in the debugger. Add a check for reference equality, or even temporarily add a GUID to your class that's setup at construction - it's easy to verify that they're the same that way.
If the new operator or the constructor is getting called twice on the object, then you have yourself two instances of the same class.
Do you need both threads to see the results of changing the private member? Or is it perfectly OK with you if both threads get the object, but when one thread changes a private member, the other thread doesn't see that change?
Here's why I ask: In your factory, you could take the object from cache and then clone or copy it before returning it. As a result, each thread would have its own copy of the class, and that copy would have the state that was in the cached object at the time they asked for it. No 2 threads would ever share the exact same instance, because you're making a copy for each thread.
If that fits your requirements, then you can avoid having to lock the object (you will need synchronization on the factory method itself though ... which you also need in your current case).
Be careful with the idea of a "clone", however. If you have a graph of objects and you only do a shallow clone, you'll wind up with references that are still shared across threads, forcing you to need synchronization again. This idea of one-copy-per-thread makes best sense if the object is a very simple object without a lot of references to other objects.

Difference between lock(locker) and lock(variable_which_I_am_using)

I'm using C# & .NEt 3.5. What is the difference between the OptionA and OptionB ?
class MyClass
{
private object m_Locker = new object();
private Dicionary<string, object> m_Hash = new Dictionary<string, object>();
public void OptionA()
{
lock(m_Locker){
// Do something with the dictionary
}
}
public void OptionB()
{
lock(m_Hash){
// Do something with the dictionary
}
}
}
I'm starting to dabble in threading (primarly for creating a cache for a multi-threaded app, NOT using the HttpCache class, since it's not attached to a web site), and I see the OptionA syntax in a lot of the examples I see online, but I don't understand what, if any, reason that is done over OptionB.
Option B uses the object to be protected to create a critical section. In some cases, this more clearly communicates the intent. If used consistently, it guarantees only one critical section for the protected object will be active at a time:
lock (m_Hash)
{
// Across all threads, I can be in one and only one of these two blocks
// Do something with the dictionary
}
lock (m_Hash)
{
// Across all threads, I can be in one and only one of these two blocks
// Do something with the dictionary
}
Option A is less restrictive. It uses a secondary object to create a critical section for the object to be protected. If multiple secondary objects are used, it's possible to have more than one critical section for the protected object active at a time.
private object m_LockerA = new object();
private object m_LockerB = new object();
lock (m_LockerA)
{
// It's possible this block is active in one thread
// while the block below is active in another
// Do something with the dictionary
}
lock (m_LockerB)
{
// It's possible this block is active in one thread
// while the block above is active in another
// Do something with the dictionary
}
Option A is equivalent to Option B if you use only one secondary object. As far as reading code, Option B's intent is clearer. If you're protecting more than one object, Option B isn't really an option.
It's important to understand that lock(m_Hash) does NOT prevent other code from using the hash. It only prevents other code from running that is also using m_Hash as its locking object.
One reason to use option A is because classes are likely to have private variables that you will use inside the lock statement. It is much easier to just use one object which you use to lock access to all of them instead of trying to use finer grain locks to lock access to just the members you will need. If you try to go with the finer grained method you will probably have to take multiple locks in some situations and then you need to make sure you are always taking them in the same order to avoid deadlocks.
Another reason to use option A is because it is possible that the reference to m_Hash will be accessible outside your class. Perhaps you have a public property which supplies access to it, or maybe you declare it as protected and derived classes can use it. In either case once external code has a reference to it, it is possible that the external code will use it for a lock. This also opens up the possibility of deadlocks since you have no way to control or know what order the lock will be taken in.
Actually, it is not good idea to lock on object if you are using its members.
Jeffrey Richter wrote in his book "CLR via C#" that there is no guarantee that a class of object that you are using for synchronization will not use lock(this) in its implementation (It's interesting, but it was a recommended way for synchronization by Microsoft for some time... Then, they found that it was a mistake), so it is always a good idea to use a special separate object for synchronization. So, as you can see OptionB will not give you a guarantee of deadlock - safety.
So, OptionA is much safer that OptionB.
It's not what you're "Locking", its the code that's contained between the lock { ... } thats important and that you're preventing from being executed.
If one thread takes out a lock() on any object, it prevents other threads from obtaining a lock on the same object, and hence prevents the second thread from executing the code between the braces.
So that's why most people just create a junk object to lock on, it prevents other threads from obtaining a lock on that same junk object.
I think the scope of the variable you "pass" in will determine the scope of the lock.
i.e. An instance variable will be in respect of the instance of the class whereas a static variable will be for the whole AppDomain.
Looking at the implementation of the collections (using Reflector), the pattern seems to follow that an instance variable called SyncRoot is declared and used for all locking operations in respect of the instance of the collection.
Well, it depends on what you wanted to lock(be made threadsafe).
Normally I would choose OptionB to provide threadsafe access to m_Hash ONLY. Where as OptionA, I would used for locking value type, which can't be used with the lock, or I had a group of objects that need locking concurrently, but I don't what to lock the whole instance by using lock(this)
Locking the object that you're using is simply a matter of convenience. An external lock object can make things simpler, and is also needed if the shared resource is private, like with a collection (in which case you use the ICollection.SyncRoot object).
OptionA is the way to go here as long as in all your code, when accessing the m_hash you use the m_Locker to lock on it.
Now Imagine this case. You lock on the object. And that object in one of the functions you call has a lock(this) code segment. In this case that is a sure unrecoverable deadlock

Categories