Why is this assignment not thread-safe? - c#

I've been reading this book from Joseph Albahari about threading:
http://www.albahari.com/threading/
In Part 2, I found this example:
http://www.albahari.com/threading/part2.aspx#_When_to_Lock
Here is the aforementioned example:
class ThreadUnsafe
{
static int _x;
static void Increment() { _x++; }
static void Assign() { _x = 123; }
}
Thread-safe version:
class ThreadSafe
{
static readonly object _locker = new object();
static int _x;
static void Increment() { lock (_locker) _x++; }
static void Assign() { lock (_locker) _x = 123; }
}
I couldn't understand why Assign method is not thread safe. Shouldn't integer assignment be atomic operation on both 32- and 64-bit architectures?

The assignment is atomic in that any reading thread will either see 123 or the previous value - not some intermediate value. However, there's no guarantee that a thread will see the new value until there have been two memory barriers: a write memory barrier in the writing thread, and a read memory barrier in the reading thread.
If you had two threads like this (after making _x public or internal, so that it could be read from other types of course - or with the code in the ThreadSafe class anyway):
// Thread 1
Console.WriteLine("Writing thread starting");
ThreadSafe.Assign();
Console.WriteLine("Writing thread done");
// Thread 2
Console.WriteLine("Reading thread starting");
while (ThreadSafe._x != 123)
{
// Do nothing
}
Console.WriteLine("Reading thread done");
... there's no guarantee that thread 2 would ever finish, because thread 2 might not "see" the assignment from thread 1.

Related

C# - Locking getter and setter of counter if multiple threads increment counter

Multiple threads are incrementing the two counters in below code but only one thread will get the value of counters. Now how to safely apply the lock on the counters while reading the counters value.
Is Interlocking needed in increment methods? is it good for performance?
locking in getStats would be sufficient to get the counters?
Also while i am getting the counters can any other threads increment the counter by calling the increment method? if yes how to mitigate that?
public sealed class StatisticsCounter
{
private static StatisticsCounter instance = null;
private static readonly object Instancelock = new object();
private volatile int Counter1 = 0;
private volatile int Counter2 = 0;
private StatisticsCounter()
{
}
public static StatisticsCounter GetInstance
{
get
{
if (instance != null)
{
lock (Instancelock)
{
if (instance == null)
{
instance = new StatisticsCounter();
}
}
}
return instance;
}
}
public void IncrementCounter1()
{
//is interlocking required? or can we do += 1.
//performance impact of interlocked
Interlocked.Increment(this.Counter1)
}
public void IncrementCounter2()
{
Interlocked.Increment(this.Counter2)
}
public string GetStats()
{
string stats = null;
//lock here will suffice?
lock (Instancelock)
{
stats = string.Format("Counter1 : {0} , Counter2 : {2}", Counter1, Counter2);
//reset
reset();
return stats;
}
}
private void reset()
{
Counter1 = 0;
Counter2 = 0;
}
}
In GetStats, the lock does not really do anything currently. But "thread safety" depend on what your requirements are.
A lock would be required if you need all the returned stats strings to equal the number of calls to the increment methods. In the current version a increment call may occur after the variables have been read, but before they have been reset. Using a lock is arguably also safer since they are just easier to understand than lock free code. If you use a lock you need to lock the same object in both the increment methods and the GetStats method, and you can remove the interlocked and volatile code, since they would not be needed if you only access the variables inside locks.
As a rule of thumb, taking a uncontested lock is fairly fast. Both your GetStats and increment methods are very short, so assuming your worker threads does other things than just incrementing the counters, I would expect the performance overhead to be fairly small. The general recommendation is to measure first, and only optimize if the performance is insufficient.
But even if the individual accesses to the count-variables are thread safe, that does not mean they will run in any particular ordering. Other synchronization might be required to ensure the calls are done in any specific order.
Also, as mentioned in the comments, just use Lazy<T> to instanciate your singleton:
private static readonly Lazy<StatisticsCounter> lazy = new (() => new StatisticsCounter());
public static StatisticsCounter GetInstance() => lazy.Value;
Assuming it actually has to be a singleton. In most cases it is better avoid global variables and just inject dependencies as constructor parameters.

Counting of threads locked

Here is the code:
private int _count = 0;
public bool Ongoing
{
get
{
return _count > 0;
}
}
public void Method1(object param)
{
new Thread(new ParameterizedThreadStart(Method2)).Start(param);
}
private void Method2(object param)
{
_count++;
lock (_lock)
{
// Something
}
_count--;
}
The variable _count, as you can guess, is used to count up how many threads are locked. It is initialized to 0 and only modified inside this method and I use it to know if the class is doing something.
Now the problem: sometimes _count goes below 0. It's like _count++ get sometimes ignored.
This happens very seldom, like about once every 500 times I start this method, maybe even less.
Should I declare _count as volatile maybe?
You need to ensure the operations are applied atomically and the value isn't cached. To achieve the first you must use Interlocked.Increment and Interlocked.Decrement, for the second mark the field as volatile:
private volatile int _count = 0;
public bool Ongoing
{
get
{
return _count > 0;
}
}
public void Method1(object param)
{
new Thread(new ParameterizedThreadStart(Method2)).Start(param);
}
private void Method2(object param)
{
Interlocked.Increment(ref _count);
lock (_lock)
{
// Something
}
Interlocked.Decrement(ref _count);
}
As has been correctly pointed out in the accepted answer, you need to perform thread synchronization around the increment and decrement operations. This can be achieved with the Interlocked class.
However, you also need to use some memory synchronization mechanism to ensure that the up-to-date value is available to other threads. The MSDN documentation on volatile is abysmally wrong:
The MSDN documentation states that use of the volatile keyword ensures that the most up-to-date value is present in the field at all times. This is incorrect, since as we’ve seen, a write followed by a read can be reordered. (Joseph Albahari)
Specifically, the volatile keyword instructs the compiler to generate an acquire-fence every read from that field. However, the acquire-fence takes effect after the read, in order to prevent other reads/writes from being moved before it. This means that the read itself may be moved up, allowing a stale value to be retrieved the first time the variable is read.
Unfortunately, there is no clean method for reading an integer with the required memory barriers, but the nearest candidate is a redundant Interlocked.CompareExchange (see this answer):
private int _count = 0;
public bool Ongoing => Interlocked.CompareExchange(ref _count, 0, 0) > 0;
public void Method1(object param)
{
new Thread(new ParameterizedThreadStart(Method2)).Start(param);
}
private void Method2(object param)
{
Interlocked.Increment(ref _count);
lock (_lock)
{
// Something
}
Interlocked.Decrement(ref _count);
}

Concurrency with reading but locking with mutating

I'm looking for a solution that allows multiple threads to read the shared resource (concurrency permitted) but then locks these reading threads once a thread enters a mutating block, to achieve best of both world.
I've looked up this reference but it seems the solution is to lock both reading and writing threads.
class Foo {
List<string> sharedResource;
public void reading() // multiple reading threads allowed, concurrency ok, lock this only if a thread enters the mutating block below.
{
}
public void mutating() // this should lock any threads entering this block as well as lock the reading threads above
{
lock(this)
{
}
}
}
Is there such a solution in C#?
Edit
All threads entering in both GetMultiton and constructor should return the same instance. want them to be thread safe.
class Foo: IFoo {
public static IFoo GetMultiton(string key, Func<IFoo> fooRef)
{
if (instances.TryGetValue(key, out IFoo obj))
{
return obj;
}
return fooRef();
}
public Foo(string key) {
instances.Add(key, this);
}
}
protected static readonly IDictionary<string, IFoo> instances = new ConcurrentDictionary<string, IFoo>();
Use
Foo.GetMultiton("key1", () => new Foo("key1"));
There is a pre-built class for this behavior ReaderWriterLockSlim
class Foo {
List<string> sharedResource;
ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
public void reading() // multiple reading threads allowed, concurrency ok, lock this only if a thread enters the mutating block below.
{
_lock.EnterReadLock();
try
{
//Do reading stuff here.
}
finally
{
_lock.ExitReadLock();
}
}
public void mutating() // this should lock any threads entering this block as well as lock the reading threads above
{
_lock.EnterWriteLock();
try
{
//Do writing stuff here.
}
finally
{
_lock.ExitWriteLock();
}
}
}
Multiple threads can enter the read lock at the same time but if a write lock tries to be taken it will block till all current readers finish then block all new writers and new readers till the write lock finishes.
With your update you don't need locks at all. Just use GetOrAdd from ConcurrentDictionary
class Foo: IFoo {
public static IFoo GetMultiton(string key, Func<IFoo> fooRef)
{
return instances.GetOrAdd(key, k=> fooRef());
}
public Foo(string key) {
instances.Add(key, this);
}
}
Note that fooRef() may be called more than once, but only the first one to return will be used as the result for all the threads. If you want fooRef() to only be called once it will require slightly more complicated code.
class Foo: IFoo {
public static IFoo GetMultiton(string key, Func<IFoo> fooRef)
{
return instances.GetOrAdd(key, k=> new Lazy<IFoo>(fooRef)).Value;
}
public Foo(string key) {
instances.Add(key, new Lazy<IFoo>(()=>this);
}
}
protected static readonly IDictionary<string, Lazy<IFoo>> instances = new ConcurrentDictionary<string, Lazy<IFoo>>();
The solution depends on your requirements. If performance of ReaderWriterLockSlim (note that it's approximately twice slower than regular lock in current .NET Framework, so maximum performance you can achieve if you modify rarely and reading is quite heavy operation, otherwise overhead will be more than profit), you can try to create copy of data, modify it and atomically swap reference with help of Interlocked class (if it's not a requirement to have the most recent data in each thread as soon as it was changed).
class Foo
{
IReadOnlyList<string> sharedResource = new List<string>();
public void reading()
{
// Here you can safely* read from sharedResource
}
public void mutating()
{
var copyOfData = new List<string>(sharedResource);
// modify copyOfData here
// Following line is correct only in case of single writer:
Interlocked.Exchange(ref sharedResource, copyOfData);
}
}
Benefits of lock-free case:
We have no locks on read, so we get maximum performance.
Drawbacks:
We have to copy data => memory traffic (allocations, garbage collection)
Reader thread can observe not the most recent update (if it reads reference before it was updated)
If reader uses sharedResource reference multiple times, then we must copy this reference to local variable via Interlocked.Exchange (if this usages of reference assume that it's the same collection)
If sharedResource is a list of mutable objects, then we must be careful with updating this objects in mutating since reader might be using them at the same moment => in this case it's better to make copies of these objects as well
If there are several updater threads, then we must use Interlocked.CompareExchange instead of Interlocked.Exchange in mutating and a kind of a loop
So, if you want to go lock-free, then it's better to use immutable objects. And anyway you will pay with memory allocations/GC for the performance.
UPDATE
Here is version that allows multiple writers as well:
class Foo
{
IReadOnlyList<string> sharedResource = new List<string>();
public void reading()
{
// Here you can safely* read from sharedResource
}
public void mutating()
{
IReadOnlyList<string> referenceToCollectionForCopying;
List<string> copyOfData;
do
{
referenceToCollectionForCopying = Volatile.Read(ref sharedResource);
copyOfData = new List<string>(referenceToCollectionForCopying);
// modify copyOfData here
} while (!ReferenceEquals(Interlocked.CompareExchange(ref sharedResource, copyOfData,
referenceToCollectionForCopying), referenceToCollectionForCopying));
}
}

Potential deadlock?

public class MyClass
{
public void DoSomething()
{
Lock(this)
{
//Do Something.
}
}
}
public class AnotherClass
{
MyClass myclass = new MyClass();
Public void DoAnotherThing()
{
lock(myclass)
{
Myclass.DoSomething();
}
}
}
Will this create a deadlock ?
As per my understanding and as per the articles I have read – It will. Why ? – Whenever DoSomething() is called it will try to attain a lock and wait for lock(myclass) to be released and hence a deadlock. Please confirm my understanding(a little explanation is also requested) and correct me if I am wrong.
I think what the articles you read were trying to tell you is that you shouldn't lock (this) because some other code might also try to lock the same object. This will only happen if two or more threads are involved.
Here's some sample code which demonstrates a deadlock problem. Try running it and look at the result.
Then make the edit suggested on the lock (this) line and try it again.
The deadlock occurs because some code OUTSIDE the class is locking on the same instance of the class that the code INSIDE the class is using for a lock - and without careful documentation and visibility, that's a real possibility.
The moral of this story is that in general you should not lock on anything that is visible outside the class (unless you document carefully how to use the locking for that class), and you should NEVER lock (this).
using System;
using System.Threading.Tasks;
namespace Demo
{
class MyClass
{
public void DoSomething()
{
Console.WriteLine("Attempting to enter the DoSomething lock.");
lock (this) // Change to lock(_locker) to prevent the deadlock.
{
Console.WriteLine("In the DoSomething lock.");
}
}
readonly object _locker = new object();
}
internal static class Program
{
static void Main(string[] args)
{
var myClass = new MyClass();
lock (myClass)
{
var task = Task.Run(() => myClass.DoSomething());
Console.WriteLine("Waiting for the task to complete.");
if (!task.Wait(1000))
Console.WriteLine("ERROR: The task did not complete.");
else
Console.WriteLine("Task completed.");
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
}
}
}
This cannot create a deadlock, because only one thread is involved. True, a lock on your MyClass object is requested when a lock on it is already held. But C# locks are "recursive", meaning that a single thread can hold multiple locks on the same object, with the result being the same as if it only held the outermost lock: The inner locks immediately succeed, and the object is locked until the last lock is released. (You don't truly understand how useful this is until you're forced to use a language which doesn't have it.)
But I agree with everyone above: lock(this) is bad juju.

Does C# have a "ThreadLocal" analog (for data members) to the "ThreadStatic" attribute?

I've found the "ThreadStatic" attribute to be extremely useful recently, but makes me now want a "ThreadLocal" type attribute that lets me have non-static data members on a per-thread basis.
Now I'm aware that this would have some non-trivial implications, but:
Does such a thing exist already built into C#/.net? or since it appears so far that the answer to this is no (for .net < 4.0), is there a commonly used implementation out there?
I can think of a reasonable way to implement it myself, but would just use something that already existed if it were available.
Straw Man example that would implement what I'm looking for if it doesn't already exist:
class Foo
{
[ThreadStatic]
static Dictionary<Object,int> threadLocalValues = new Dictionary<Object,int>();
int defaultValue = 0;
int ThreadLocalMember
{
get
{
int value = defaultValue;
if( ! threadLocalValues.TryGetValue(this, out value) )
{
threadLocalValues[this] = value;
}
return value;
}
set { threadLocalValues[this] = value; }
}
}
Please forgive any C# ignorance. I'm a C++ developer that has only recently been getting into the more interesting features of C# and .net
I'm limited to .net 3.0 and maybe 3.5 (project has/will soon move to 3.5).
Specific use-case is callback lists that are thread specific (using imaginary [ThreadLocal] attribute) a la:
class NonSingletonSharedThing
{
[ThreadLocal] List<Callback> callbacks;
public void ThreadLocalRegisterCallback( Callback somecallback )
{
callbacks.Add(somecallback);
}
public void ThreadLocalDoCallbacks();
{
foreach( var callback in callbacks )
callback.invoke();
}
}
Enter .NET 4.0!
If you're stuck in 3.5 (or earlier), there are some functions you should look at, like AllocateDataSlot which should do what you want.
You should think about this twice. You are essentially creating a memory leak. Every object created by the thread stays referenced and can't be garbage collected. Until the thread ends.
If you looking to store unique data on a per thread basis you could use Thread.SetData. Be sure to read up on the pros and cons http://msdn.microsoft.com/en-us/library/6sby1byh.aspx as this has performance implications.
Consider:
Rather than try to give each member variable in an object a thread-specific value, give each thread its own object instance. -- pass the object to the threadstart as state, or make the threadstart method a member of the object that the thread will "own", and create a new instance for each thread that you spawn.
Edit
(in response to Catskul's remark.
Here's an example of encapsulating the struct
public class TheStructWorkerClass
{
private StructData TheStruct;
public TheStructWorkerClass(StructData yourStruct)
{
this.TheStruct = yourStruct;
}
public void ExecuteAsync()
{
System.Threading.ThreadPool.QueueUserWorkItem(this.TheWorkerMethod);
}
private void TheWorkerMethod(object state)
{
// your processing logic here
// you can access your structure as this.TheStruct;
// only this thread has access to the struct (as long as you don't pass the struct
// to another worker class)
}
}
// now hte code that launches the async process does this:
var worker = new TheStructWorkerClass(yourStruct);
worker.ExecuteAsync();
Now here's option 2 (pass the struct as state)
{
// (from somewhere in your existing code
System.Threading.Threadpool.QueueUserWorkItem(this.TheWorker, myStruct);
}
private void TheWorker(object state)
{
StructData yourStruct = (StructData)state;
// now do stuff with your struct
// works fine as long as you never pass the same instance of your struct to 2 different threads.
}
I ended up implementing and testing a version of what I had originally suggested:
public class ThreadLocal<T>
{
[ThreadStatic] private static Dictionary<object, T> _lookupTable;
private Dictionary<object, T> LookupTable
{
get
{
if ( _lookupTable == null)
_lookupTable = new Dictionary<object, T>();
return _lookupTable;
}
}
private object key = new object(); //lazy hash key creation handles replacement
private T originalValue;
public ThreadLocal( T value )
{
originalValue = value;
}
~ThreadLocal()
{
LookupTable.Remove(key);
}
public void Set( T value)
{
LookupTable[key] = value;
}
public T Get()
{
T returnValue = default(T);
if (!LookupTable.TryGetValue(key, out returnValue))
Set(originalValue);
return returnValue;
}
}
Although I am still not sure about when your use case would make sense (see my comment on the question itself), I would like to contribute a working example that is in my opinion more readable than thread-local storage (whether static or instance). The example is using .NET 3.5:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Linq;
namespace SimulatedThreadLocal
{
public sealed class Notifier
{
public void Register(Func<string> callback)
{
var id = Thread.CurrentThread.ManagedThreadId;
lock (this._callbacks)
{
List<Func<string>> list;
if (!this._callbacks.TryGetValue(id, out list))
{
this._callbacks[id] = list = new List<Func<string>>();
}
list.Add(callback);
}
}
public void Execute()
{
var id = Thread.CurrentThread.ManagedThreadId;
IEnumerable<Func<string>> threadCallbacks;
string status;
lock (this._callbacks)
{
status = string.Format("Notifier has callbacks from {0} threads, total {1} callbacks{2}Executing on thread {3}",
this._callbacks.Count,
this._callbacks.SelectMany(d => d.Value).Count(),
Environment.NewLine,
Thread.CurrentThread.ManagedThreadId);
threadCallbacks = this._callbacks[id]; // we can use the original collection, as only this thread can add to it and we're not going to be adding right now
}
var b = new StringBuilder();
foreach (var callback in threadCallbacks)
{
b.AppendLine(callback());
}
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine(status);
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(b.ToString());
}
private readonly Dictionary<int, List<Func<string>>> _callbacks = new Dictionary<int, List<Func<string>>>();
}
public static class Program
{
public static void Main(string[] args)
{
try
{
var notifier = new Notifier();
var syncMainThread = new ManualResetEvent(false);
var syncWorkerThread = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(delegate // will create closure to see notifier and sync* events
{
notifier.Register(() => string.Format("Worker thread callback A (thread ID = {0})", Thread.CurrentThread.ManagedThreadId));
syncMainThread.Set();
syncWorkerThread.WaitOne(); // wait for main thread to execute notifications in its context
syncWorkerThread.Reset();
notifier.Execute();
notifier.Register(() => string.Format("Worker thread callback B (thread ID = {0})", Thread.CurrentThread.ManagedThreadId));
syncMainThread.Set();
syncWorkerThread.WaitOne(); // wait for main thread to execute notifications in its context
syncWorkerThread.Reset();
notifier.Execute();
syncMainThread.Set();
});
notifier.Register(() => string.Format("Main thread callback A (thread ID = {0})", Thread.CurrentThread.ManagedThreadId));
syncMainThread.WaitOne(); // wait for worker thread to add its notification
syncMainThread.Reset();
notifier.Execute();
syncWorkerThread.Set();
syncMainThread.WaitOne(); // wait for worker thread to execute notifications in its context
syncMainThread.Reset();
notifier.Register(() => string.Format("Main thread callback B (thread ID = {0})", Thread.CurrentThread.ManagedThreadId));
notifier.Execute();
syncWorkerThread.Set();
syncMainThread.WaitOne(); // wait for worker thread to execute notifications in its context
syncMainThread.Reset();
}
finally
{
Console.ResetColor();
}
}
}
}
When you compile and run the above program, you should get output like this:
alt text http://img695.imageshack.us/img695/991/threadlocal.png
Based on your use-case I assume this is what you're trying to achieve. The example first adds two callbacks from two different contexts, main and worker threads. Then the example runs notification first from main and then from worker threads. The callbacks that are executed are effectively filtered by current thread ID. Just to show things are working as expected, the example adds two more callbacks (for a total of 4) and again runs the notification from the context of main and worker threads.
Note that Notifier class is a regular instance that can have state, multiple instances, etc (again, as per your question's use-case). No static or thread-static or thread-local is used by the example.
I would appreciate if you could look at the code and let me know if I misunderstood what you're trying to achieve or if a technique like this would meet your needs.
I'm not sure how you're spawning your threads in the first place, but there are ways to give each thread its own thread-local storage, without using hackish workarounds like the code you posted in your question.
public void SpawnSomeThreads(int threads)
{
for (int i = 0; i < threads; i++)
{
Thread t = new Thread(WorkerThread);
WorkerThreadContext context = new WorkerThreadContext
{
// whatever data the thread needs passed into it
};
t.Start(context);
}
}
private class WorkerThreadContext
{
public string Data { get; set; }
public int OtherData { get; set; }
}
private void WorkerThread(object parameter)
{
WorkerThreadContext context = (WorkerThreadContext) parameter;
// do work here
}
This obviously ignores waiting on the threads to finish their work, making sure accesses to any shared state is thread-safe across all the worker threads, but you get the idea.
Whilst the posted solution looks elegant, it leaks objects. The finalizer - LookupTable.Remove(key) - is run only in the context of the GC thread so is likely only creating more garbage in creating another lookup table.
You need to remove object from the lookup table of every thread that has accessed the ThreadLocal. The only elegant way I can think of solving this is via a weak keyed dictionary - a data structure which is strangely lacking from c#.

Categories

Resources