have another confusion about locking in C#.
The problem is sharing a state among diffrent threads.
Following scenario:
A thread processes a state machine. This machine, for example, counts up a value with delay. The machine thread reads this value and increments. Other threads shall now be able to read this count value. Actually I have more values than just a a single count, so I prepared a class which holds the shared values. This looks like this:
IStatus is a suitable private interface. Summaries are removed since not in English.
public class Status : ICloneable, IStatus
{
private object locker;
public bool Run { get; private set; }
public uint SecondRemain { get; private set; }
// ... and some more value types
public Status()
{
locker = new object();
}
void IStatus.SetRun(bool enable)
{
lock (locker)
{
Run = enable;
}
}
void IStatus.SetSecondRemain (uint value)
{
lock (locker)
{
SecondRemain = value;
}
}
// ... and some more set of value types
public object Clone()
{
object copy;
lock (locker)
{
copy = MemberwiseClone();
// Since it is a "new" object, we decouple the lock
((Status)copy).locker = new object();
}
return copy;
}
In main class where the state machine and its thread lives in:
private Status shared;
// Shall be accessible by any thread at any time
public Status GetStatus()
{
// Clones thread-safe, fenced by locker
return (Status) shared.Clone();
}
// Will be accessed only by inner thread
private void AnyMethodCalledStateMachineThread()
{
// Get the current remaining second value.
// No fence here ??
uint value = shared.SecondRemain;
// fences by locker
((IStatus) shared).SetSecondRemain (value++);
}
What we see now is, only the inner thread will read and write to some values. This thread will read what it has previously written. To ensure other threads can read this, it is locked.
External threads can only get a full copy by lock statement.
But does internal thread itself needs lock, too, when reading single properties or do I have to put lock around these properties (with extra field)?
EDIT
This is the requested sort of code which runs the thread
var thread;
private void Start()
{
thread = new Thread(new ThreadStart(ProducerMain));
thread.Start();
}
// Example, no real code
private void ProducerMain()
{
while ( ...)
{
Thread.Sleep(1000);
AnyMethodCalledStateMachineThread();
}
}
Related
I have a class that has the fields: array of messages and current number of messages and the methods read\write.
When someone write, it puts the message into the array and increment current number of messages by one, and when someone trying to read it first decrease
current number of messages and then returns the last message.
I want to make this class to be Synchronized so it will allow to threads to write and read(when the array is empty i want that the thread will wait until will be something to read) from him and prevent data races.
I did this class that implements :
class SynchronizedDATAStructure : DATAStructure
{
private Mutex mutexR = new Mutex();
private Mutex mutexW = new Mutex();
private Semaphore semaphore = new Semaphore(0, int.MaxValue);
private Semaphore semaphore2 = new Semaphore(1, 1);
public override void Write(Message msg)
{
mutexW.WaitOne(); // allows only one thread each time to write
semaphore2.WaitOne(); // checks if nobody is reading
base.Write(msg); // writing
semaphore.Release(); // counts number of messages
semaphore2.Release(); // finish to write
mutexW.ReleaseMutex(); // finish the function
}
public override Message Read()
{
mutexR.WaitOne(); // allows only one thread each time to read
semaphore.WaitOne(); // checks if there are messages
semaphore2.WaitOne(); // checks if nobody is writing
Message msg1 = base.Read(); // reading
semaphore2.Release(); // finish to read
mutexR.ReleaseMutex(); // finish the function
return msg1; // returns the messge
}
When the threads start to write\read i got outOfBounds after while when thread trying to read from empty array.
You can make your code much simpler using Monitor:
class SynchronizedDATAStructure : DATAStructure
{
private readonly object syncRoot = new object();
public int MessageCount { get; private set; }
public override void Write(Message msg)
{
lock (syncRoot)
{
base.Write(msg);
MessageCount++;
Monitor.Pulse(syncRoot);
}
}
public override Message Read()
{
lock (syncRoot)
{
while (MessageCount <= 0)
{
Monitor.Wait(syncRoot);
}
MessageCount--;
return base.Read();
}
}
}
Question regarding locking, with text referring to the sample code below...I have a class (Class1) which provides a public List property called Class1Resources. 2 methods in Class1 provide basic query capability on Class1Resources. In addition, Class1 also subscribes to an event from a different service which provides notification that Class1 should update this Class1Resources object.
My question is, what and where should locking be implemented such that the 2 public methods which query Class1Resources are blocked when ExternalAppCallback is executing, thereby ensuring that the query methods are always using the most current data? Is the commented code I have in ExternalAppCallback the proper way to do this?
public class Class1
{
public List<Resource> Class1Resources { get; private set; }
public Class1()
{
// subscribe to external app event, with callback = ExternalAppCallback
}
private void ExternalAppCallback(List<Resource> updatedResourceList)
{
// do I put the lock here as in the code below?
//lock(someObject)
//{
// Class1Resources = new List<Resource>(updatedResourceList);
//}
Class1Resources = new List<Resource>(updatedResourceList);
}
public List<Resource> GetResourcesByCriteria1(string criteria1)
{
return Class1Resources.Where(r => r.Criteria1 == criteria1).ToList();
}
public List<Resource> GetResourcesByCriteria2(string criteria2)
{
return Class1Resources.Where(r => r.Criteria2 == criteria2).ToList();
}
}
I'm interpreting your question as "how do I effectively make Class1Resources thread safe?" and so I would recommend either a classic lock or, if you expect writes/changes to be seldom, a ReaderWriterLockSlim. Here is how you'd use a lock in your class to ensure thread safety / consistent data:
public class Class1
{
// Here's your object to lock on
private readonly object _lockObject = new object();
// NOTE: made this private to control how it is exposed!
private List<Resource> Class1Resources = null;
public Class1()
{
// subscribe to external app event, with callback = ExternalAppCallback
}
private void ExternalAppCallback(List<Resource> updatedResourceList)
{
// Setting a reference is always atomic, no need to lock this
Class1Resources = new List<Resource>(updatedResourceList);
}
// Your new method to expose the list in a thread-safe manner
public List<Resource> GetResources()
{
lock (_lockObject)
{
// ToList() makes a copy of the list versus maintaining the original reference
return Class1Resources.ToList();
}
}
public List<Resource> GetResourcesByCriteria1(string criteria1)
{
lock (_lockObject)
{
return Class1Resources.Where(r => r.Criteria1 == criteria1).ToList();
}
}
public List<Resource> GetResourcesByCriteria2(string criteria2)
{
lock (_lockObject)
{
return Class1Resources.Where(r => r.Criteria2 == criteria2).ToList();
}
}
}
Note that in this solution, anything calling the getter of your property will not be using the lock and thus will cause thread safety issues. This is why I changed the code to make it a private member.
Question, Let's say I had Thread A and Thread B and both of these needed access to a singleton object and it's properties.
Currently the singleton looks as follows.
public class Singleton{
#region fields
private static Singleton singletonObject;
private double value1= 0;
private double value2= 0;
private double value3= 0;
private double value4= 0;
private object locker = null;
#endregion
// private constructor. This will avoid creating object using new keyword
private Singleton() {
locker = new object();
}
// public method which will be called
public void GetName() {
Console.WriteLine("singleton Object");
}
public static Singleton Instance() {
// this object will be used with lock, so that it will be always one thread which will be executing the code
object instanceLocker = new object();
// put a lock on myObject. We won't be able to use singleTonObject becuase it will be null. lock is to make the object thread safe.
// lock can't be worked with null objects.
lock (instanceLocker) {
// check whether the instance was there. If it's not there, then create an instance.
if (singletonObject == null) {
singletonObject = new Singleton();
}
}
return singletonObject;
}
public double Value1 { get { lock (locker) { return value1; } } set { lock (locker) { value1= value; } } }
public double Value2 { get { lock (locker) { return value2; } } set { lock (locker) { value2= value; } } }
public double Value3 { get { lock (locker) { return value3; } } set { lock (locker) { value3= value; } } }
public double Value4 { get { lock (locker) { return value4; } } set { lock (locker) { value4= value; } } }
}
My question. Rather than having thread safe properties, is there a better approach?
Thanks,
Currently your code is completely broken. You're creating a new object to lock on during every call. No other thread will ever know about it, so it's completely pointless.
Don't bother trying to fix it in clever ways. Just initialize it in the static variable initializer:
private static Singleton singletonObject = new Singleton();
Nice and simple.
For more information about implementing the singleton pattern in C# (including using Lazy<T> in .NET 4), see my article on the topic.
Aside from the fact that you're creating a new object to lock on for every call, there is another fundamental problem: even if you do have the same object, you're still not really protecting anything.
Somewhere along the line you initialize Value1 to 9:
Singleton.Instance().Value1 = 9;
Now let's say you have two threads executing this code:
public void Foo()
{
Singleton.Instance().Value1++;
if(Singleton.Instance().Value1==10.0)
{
Singleton.Instance().Value2 = 20.0;
}
else
{
Singleton.Instance().Value3 = 30.0;
}
}
Thread A calls Value1++ and incrementing value1 to 10.0
Thread B calls Value1++ and now the value1 is 11.0
Thread A checks if the value value1 is 10.0 -> returns false!
Thread A sets Value3 to 30
Thread B sets Value3 to 30 also.
This is just a very simple example where locking the properties will not protect you since the external code does nothing to guarantee the order in which things are being read or written. There could be a number of other orders in which Thread A and Thread B are executed which will result in completely different outcomes.
This behavior may be OK, since you could have let the user of the Singleton class take the responsibility for ensuring the correct operation outside your class, but it's generally something you should be aware of. Simply locking the properties will not eliminate the read/write contention.
Are you using .NET 4.0? Instead of locking, you can use ConCurrent collections for thread safe activity.
I post my understanding of C# lock as follows, please help me validate whether or not I get it right.
public class TestLock
{
private object threadLock = new object();
...
public void PrintOne()
{
lock (threadLock)
{
// SectionOne
}
}
public void PrintTwo()
{
lock (threadLock)
{
// SectionTwo
}
}
...
}
Case I> Thread1 and Thread2 simultaneously try to call PrintOne.
Since PrintOne is guarded by the instance lock, at any time, only
one thread can exclusively enter the SectionOne.
Is this correct?
Case II> Thread1 and Thread2 simultaneously try to call PrintOne and PrintTwo
respectively (i.e. Thread1 calls PrintOne and Thread2 calls PrintTwo)
Since two print methods are guarded by the same instance lock, at any time,
only one thread can exclusively access either SectionOne or SectionTwo, but NOT both.
Is this correct?
1 and 2 are true only if all your threads use the same instance of the class. If they use different instances, then both cases are false
Sample
public class TestLock
{
private object threadLock = new object();
public void PrintOne()
{
lock (threadLock)
{
Console.WriteLine("One");
var f = File.OpenWrite(#"C:\temp\file.txt"); //same static resource
f.Close();
}
}
public void PrintTwo()
{
lock (threadLock)
{
Console.WriteLine("Two");
var f = File.OpenWrite(#"C:\temp\file.txt"); //same static resource
f.Close();
}
}
}
And testing code
static void Main(string[] args)
{
int caseNumber = 100;
var threads = new Thread[caseNumber];
for (int i = 0; i < caseNumber; i++)
{
var t = new Thread(() =>
{
//create new instance
var testLock = new TestLock();
//for this instance we safe
testLock.PrintOne();
testLock.PrintTwo();
});
t.Start();
//once created more than one thread, we are unsafe
}
}
One of the possible solutions is to add a static keyword to the locking object declaration and methods that use it.
private static object threadLock = new object();
UPDATE
Good point made by konrad.kruczynski
..."thread safety" is also assumed from
context. For example, I could take
your file opening code and also
generate exception with static lock -
just taking another application
domain. And therefore propose that OP
should use system-wide Mutex class or
sth like that. Therefore static case
is just inferred as the instance one.
Case I: Check ✓
Case II: Check ✓
Don't forget that locking is only one way of thread synchronization. For other userfull methods, read: Thread Synchronization
Straight from MSDN sample:
public class TestThreading
{
private System.Object lockThis = new System.Object();
public void Process()
{
lock (lockThis)
{
// Access thread-sensitive resources.
}
}
}
Yes and yes. Cases are correct.
Your understanding is 100% correct. So if, for instance, you wanted to allow entry into the two methods separately you would want to have two locks.
Yes, you're correct in both counts.
here are the basics (more or less)
1) use instance locks for instance data
public class InstanceOnlyClass{
private int callCount;
private object lockObject = new object();
public void CallMe()
{
lock(lockObject)
{
callCount++;
}
}
}
2) use static locks for static data
public class StaticOnlyClass{
private int createdObjects;
private static object staticLockObject = new object();
public StaticOnlyClass()
{
lock(staticLockObject)
{
createdObjects++;
}
}
}
3) if you are protecting static and instance data use separate static and instance locks
public class StaticAndInstanceClass{
private int createdObjects;
private static object staticLockObject = new object();
private int callCount;
private object lockObject = new object();
public StaticAndInstanceClass()
{
lock(staticLockObject)
{
createdObjects++;
}
}
public void CallMe()
{
lock(lockObject)
{
callCount++;
}
}
}
based on this your code is fine if you are accessing instance data but unsafe if you are modifying static data
For a "log information for support" type of function I'd like to enumerate and dump active thread information.
I'm well aware of the fact that race conditions can make this information semi-inaccurate, but I'd like to try to get the best possible result, even if it isn't 100% accurate.
I looked at Process.Threads, but it returns ProcessThread objects, I'd like to have a collection of Thread objects, so that I can log their name, and whether they're background threads or not.
Is there such a collection available, even if it is just a snapshot of the active threads when I call it?
ie.
Thread[] activeThreads = ??
Note, to be clear, I am not asking about Process.Threads, this collection gives me a lot, but not all of what I want. I want to know how much time specific named threads in our application is currently using (which means I will have to look at connecting the two types of objects later, but the names is more important than the CPU time to begin with.)
If you're willing to replace your application's Thread creations with another wrapper class, said wrapper class can track the active and inactive Threads for you. Here's a minimal workable shell of such a wrapper:
namespace ThreadTracker
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
public class TrackedThread
{
private static readonly IList<Thread> threadList = new List<Thread>();
private readonly Thread thread;
private readonly ParameterizedThreadStart start1;
private readonly ThreadStart start2;
public TrackedThread(ParameterizedThreadStart start)
{
this.start1 = start;
this.thread = new Thread(this.StartThreadParameterized);
lock (threadList)
{
threadList.Add(this.thread);
}
}
public TrackedThread(ThreadStart start)
{
this.start2 = start;
this.thread = new Thread(this.StartThread);
lock (threadList)
{
threadList.Add(this.thread);
}
}
public TrackedThread(ParameterizedThreadStart start, int maxStackSize)
{
this.start1 = start;
this.thread = new Thread(this.StartThreadParameterized, maxStackSize);
lock (threadList)
{
threadList.Add(this.thread);
}
}
public TrackedThread(ThreadStart start, int maxStackSize)
{
this.start2 = start;
this.thread = new Thread(this.StartThread, maxStackSize);
lock (threadList)
{
threadList.Add(this.thread);
}
}
public static int Count
{
get
{
lock (threadList)
{
return threadList.Count;
}
}
}
public static IEnumerable<Thread> ThreadList
{
get
{
lock (threadList)
{
return new ReadOnlyCollection<Thread>(threadList);
}
}
}
// either: (a) expose the thread object itself via a property or,
// (b) expose the other Thread public methods you need to replicate.
// This example uses (a).
public Thread Thread
{
get
{
return this.thread;
}
}
private void StartThreadParameterized(object obj)
{
try
{
this.start1(obj);
}
finally
{
lock (threadList)
{
threadList.Remove(this.thread);
}
}
}
private void StartThread()
{
try
{
this.start2();
}
finally
{
lock (threadList)
{
threadList.Remove(this.thread);
}
}
}
}
}
and a quick test driver of it (note I do not iterate over the list of threads, merely get the count in the list):
namespace ThreadTracker
{
using System;
using System.Threading;
internal static class Program
{
private static void Main()
{
var thread1 = new TrackedThread(DoNothingForFiveSeconds);
var thread2 = new TrackedThread(DoNothingForTenSeconds);
var thread3 = new TrackedThread(DoNothingForSomeTime);
thread1.Thread.Start();
thread2.Thread.Start();
thread3.Thread.Start(15);
while (TrackedThread.Count > 0)
{
Console.WriteLine(TrackedThread.Count);
}
Console.ReadLine();
}
private static void DoNothingForFiveSeconds()
{
Thread.Sleep(5000);
}
private static void DoNothingForTenSeconds()
{
Thread.Sleep(10000);
}
private static void DoNothingForSomeTime(object seconds)
{
Thread.Sleep(1000 * (int)seconds);
}
}
}
Not sure if you can go such a route, but it will accomplish the goal if you're able to incorporate at an early stage of development.
Is it feasible for you to store thread information in a lookup as you create each thread in your application?
As each thread starts, you can get its ID using AppDomain.GetCurrentThreadId(). Later, you can use this to cross reference with the data returned from Process.Threads.