Imagine this code:
public class Kitchen(){
private readonly Mutex kitchenLock = new Mutex(true, "Kitchen");
private readonly object _lock = new Object();
public void Enter(){
lock(_lock){
kitchenLock.WaitOne(-1); //wait indefinitely
}
}
public void DoCooking(){
//cook stuff...
}
public void Leave(){
lock(_lock){
kitchenLock.ReleaseMutex();
}
}
}
On my function bellow, called by a zillion of different and bad behaved threads i do this:
Kitchen kit = new Kitchen();
kit.Enter();
kit.DoCooking();
kit.Leave();
Everything is fine in the code above. But the kit.Leave() throws a AbandonMutexException, why is that? Can find an answer... I muted the exception and it works fine. Is it a safe guard of .NET?
It is a very serious threading bug, you cannot ignore it. Your code is calling Enter() but not Leave(). Which gets you a mutex that is acquired but will never be released, a guaranteed recipe for deadlock.
Luckily, .NET can detect the mishap, the thread that owns the mutex stopped running which automatically means it is never going to call ReleaseMutex(). That's always bad, so it raises the exception to help you realize that your code has a deadlock bug. At the very minimum, you need a hard guarantee that ReleaseMutex() is always called, even if there's an exception:
Kitchen kit = new Kitchen();
kit.Enter();
try {
kit.DoCooking();
}
finally {
kit.Leave();
}
Albeit that the code looks too fake to be actually usable as-is.
Thanks everyone that tried to answer my question, but I've found the answer myself.
Besides the comments regarding bugs, there is no bug in this code :) (sorry), instead there is a misunderstand of the meaning of initiallyOwned parameter when instantiating the kitchen mutex.
Mutex MSDN documentation can be found here and says:
Initializes a new instance of the Mutex class with a Boolean value that indicates whether the
calling thread should have initial ownership of the mutex, and a string that is the name of the
mutex.
But at the beginning that didn't make much sense, so I thought yes the creating thread should own the mutex, why not? don't even know what this means, but sound good!
Although after seeing all MSDN examples regarding this I understood what it means to be initiallyOwned, initiallyOwned means that the thread that creates mutex has an implicit call to the mutex WaitOne method, meaning, obviously, that the thread Initially OWNS IT!
Here is an MSDN example:
// Create a new Mutex. The creating thread owns the
// Mutex.
private static Mutex mut = new Mutex(true);
private const int numIterations = 1;
private const int numThreads = 3;
static void Main()
{
// Create the threads that will use the protected resource.
for(int i = 0; i < numThreads; i++)
{
Thread myThread = new Thread(new ThreadStart(MyThreadProc));
myThread.Name = String.Format("Thread{0}", i + 1);
myThread.Start();
}
// Wait one second before allowing other threads to
// acquire the Mutex.
Console.WriteLine("Creating thread owns the Mutex.");
Thread.Sleep(1000);
Console.WriteLine("Creating thread releases the Mutex.\r\n");
mut.ReleaseMutex();
}
private static void MyThreadProc()
{
for(int i = 0; i < numIterations; i++)
{
UseResource();
}
}
// This method represents a resource that must be synchronized
// so that only one thread at a time can enter.
private static void UseResource()
{
// Wait until it is safe to enter.
mut.WaitOne();
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name);
// Place code to access non-reentrant resources here.
// Simulate some work.
Thread.Sleep(500);
Console.WriteLine("{0} is leaving the protected area\r\n",
Thread.CurrentThread.Name);
// Release the Mutex.
mut.ReleaseMutex();
}
So as you can see Main does not call mut.WaitOne(-1) if it had called it like I DO in my example it means that the thread running main would have to call ReleaseMutex 2 times instead of just one.
You can be wondering, what?! But how can the thread call 2 times WaitOne, are you mad, actually this is very interesting, because since the thread calling Main initially owns the Mutex, it would have to ReleaseMutex also 2 times, as specified here:
If a thread owns a Mutex, that thread can specify the same Mutex in repeated wait-request calls
without blocking its execution; however, it must release the Mutex as many times to release
ownership.
And that's it,
Regards.
Related
I have some code that I have been going over to learn the system and I ran across some code that to me is a code smell and I wouldn't think it would work at all, but it does.
We have two objects, object A and object B. Object A contains a lock object:
private object lockObj = new object();
Object B will grab a lock on object A.lockObj and while B has the lock it calls
A.SomeMethod();
A.SomeMethod() acquires a lock on
this.lockObj
And to show it in code:
ThreadTestOne:
public class ThreadTestOne
{
public object lockObject = new object();
private List<string> lst;
private ThreadTestTwo two;
public List<string> Lst
{
get
{
return this.lst;
}
set
{
this.lst = value;
}
}
public void Run()
{
lst = new List<string>();
two = new ThreadTestTwo();
two.Run(this);
}
public void End()
{
Console.WriteLine("ThreadTestOne.End");
two.End();
}
public void LockMe()
{
Console.WriteLine("ThreadTestOne.LockMe");
lock (this.lockObject)
lst.Add("something");
Thread.Sleep(500);
}
}
ThreadTestTwo:
public class ThreadTestTwo
{
private ThreadTestOne one;
private Thread myThread;
private bool ending = false;
public void Run(ThreadTestOne a)
{
one = a;
myThread = new Thread(new ThreadStart(Consume));
Console.WriteLine("ThreadTestTwo Starting thread");
myThread.Start();
}
public void End()
{
Console.WriteLine("ThreadTestTwo.End");
ending = true;
myThread.Join();
}
public void Consume()
{
while (!ending)
{
Console.WriteLine("ThreadTestTwo one.lockObject");
lock (one.lockObject)
{
Console.WriteLine("two.LockMe");
one.LockMe();
one.Lst.Add("two");
Thread.Sleep(500);
}
}
}
}
When I look over the above code, I think it should break as one.LockMe() should never be able to acquire a lock on lockObj because it ThreadTestTwo already has the lock.
I thought this would result in a deadlock. However, when I run the above example code, it works. Also, the code I was reviewing also works and is currently in production.
The fact that this doesn't result in an exception being thrown is confusing to me. Am I incorrect in assuming this should be an error?
In the code that I was testing originally only reading data after trying to acquire the lock twice so I had thought that the compiler was removing the lock.
However, I looked in the MSIL and saw that the lock is still there.
My next thought was the framework just wasn't acquiring the lock because we are just reading data.
I add a write operation within the lock and it still worked. However, it is possible that I don't fully understand how locking work.
Even though this works, I feel that it is wrong and I am not fully convinced that this will not cause issues in production.
I did find this question:
use the same lock object at two different code block?
Which is similar but I believe my issue is slightly different, I'm asking about locking an object when the calling method has already has a lock on that same object.
Obviously the code I have a question about works and I would like to know how?
Am I incorrect in assuming this is wrong?
There are a couple of issues that I am aware of in the above code.
public field - I know this is wrong, but that is how it is in the code.
Circular reference - I'm aware of the circular reference and know why it is bad.
Thank you for any insight you can provide.
You seem to be under the impression that a class owns a lock (aka monitor). That's not the case - a thread owns a monitor.
Monitors in .NET are re-entrant - if a thread already has the monitor, it can acquire it again. That will increase the "lock count" for it - when the thread releases the monitor the first time, it will just decrease the lock count, but as the count will still be positive, no other thread will be able to acquire the monitor until the original thread has released it again.
From Monitor.Enter (the method that the lock keyword sort-of calls - it actually calls TryEnter, but...):
It is legal for the same thread to invoke Enter more than once without it blocking; however, an equal number of Exit calls must be invoked before other threads waiting on the object will unblock.
I'm very new to threading, so I'm not sure if I'm doing this right, but would appreciate some assistance. I have the following code to run when the user clicks the mouse; it basically runs some path-finding code and moves the player.
However, my problem is when I click the mouse again while the thread is running, it causes issues. Is there a way to stop the previous thread and start a new one when this code is reached a second time?
private void checkMouse()
{
mouseCommand mc = new mouseCommand();
Thread oThread = new Thread(() => mc.leftClick(Mouse.GetState().X,Mouse.GetState().Y));
oThread.Start();
}
Perhaps something like this would work for you?
private object lock_object - new object();
private Thread oThread = new Thread();
private void checkMouse()
{
lock(lock_object)
{
if (oThread.ThreadState != ThreadState.Running)
{
mouseCommand mc = new mouseCommand();
oThread = new Thread(() => mc.leftClick(Mouse.GetState().X,Mouse.GetState().Y));
oThread.Start();
}
}
}
There's a few ways you can do this.
The simplest, and the first you should learn about when learning about threading is a lock. Have an object that you use to lock on this and any related actions that would also cause problem if they happened together:
private object lockObj = new object();
private static void DoLClick()
{
lock(lockObj)
{
mouseCommand mc = new mouseCommand();
mc.leftClick(Mouse.GetState().X,Mouse.GetState().Y));
}
}
private void checkMouse()
{
Thread oThread = new Thread(DoLClick);
oThread.Start();
}
The benefit is that this keeps threads from stepping on each other toes.
The downside is the loss of concurrency (all these threads are waiting on each other, instead of doing something) and the risk of deadlock (if thread A has lock 1 and needs lock 2 and thread B has lock 2 and needs lock 1, you're stuck).
It remains the simplest approach. Often even if you're going to need to use another approach, it's well worth starting with some widely defined locks, and then changing to narrower locks (that is, locks that cover less code) or different approaches later.
Another possibility is to have a lock, but instead of using lock(){} to obtain it, you use Monitor.TryEnter() with a time-out (perhaps of zero) and just give up if you don't get it:
private object lockObj = new object();
private static void DoLClick()
{
if(!Monitor.TryEnter(lockObj, 0))
return; // Just do nothing if we're busy.
try
{
mouseCommand mc = new mouseCommand();
mc.leftClick(Mouse.GetState().X,Mouse.GetState().Y));
}
finally
{
Monitor.Exit(lockObj);
}
}
private void checkMouse()
{
Thread oThread = new Thread(DoLClick);
oThread.Start();
}
The downside is that you don't get that second task done. The upside is that you often don't want something done if it's already being done, and you get that for free.
Some other approaches are a variant of this, where you've a thread-safe object describing tasks to do; it could be an integer count of actions that need doing that you use Interlocked.Increment() and Interlocked.Decrement() to change, or a ConcurrentQueue of objects that describe the task that needs doing. Then you could have the thread that failed to get the lock add to that, and that which did get the lock take over that thread's work when it's finished. Or you could perhaps have a dedicated thread that just keeps looking for work to do, and waits on an AutoResetEvent whenever it runs out of work - threads giving it work (adding to the queue) set that event to make sure it's not just sitting doing nothing.
All these possibilities (and more) are worth learning about, and have their place, but the first suggestion with lock is the first to learn.
I have some trouble with threading in my application. I have a multi-threaded client/server application. I'm also using C# MonoDevelop for Unity3d. Not sure if it makes any difference for the answer. I'll try to explain where my problem is:
Unity works on a single thread. So if i want to instantiate an object which uses the abstract class ScriptableObject from unity, then this must be done on the main thread on which Unity runs.
But my server socket spawns a thread for every connected client, so that incoming data can be processed async. The received data is processed in the OnDataReceived() method (which runs on its own thread)
The problem here is, is that i can't create an instance of a Player object inside the OnDataReceived() thread. Because my Player object inherits from ScriptableObject. Which means this object should be created on the main Unity thread.
But i have no idea how to do that... Is there a way to switch back to the main thread, so i can still create a Player object in the OnDataReceived() method?
.NET already has a concept of a SynchronizationContext, most often used for UI apps where thread affinity is required to invoke operations on UI controls (e.g. in WPF or WinForms). However, even outside a UI app, you can reuse these concepts for a general purpose thread-affinitized work queue.
This sample shows how to use the WPF DispatcherSynchronizationContext (from WindowsBase.dll) in a simple console application, together with the .NET 4.0 task classes (TaskScheduler / Task) to invoke actions originating on child threads back on the main program thread.
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
internal sealed class Program
{
private static void Main(string[] args)
{
int threadCount = 2;
using (ThreadData data = new ThreadData(threadCount))
{
Thread[] threads = new Thread[threadCount];
for (int i = 0; i < threadCount; ++i)
{
threads[i] = new Thread(DoOperations);
}
foreach (Thread thread in threads)
{
thread.Start(data);
}
Console.WriteLine("Starting...");
// Start and wait here while all work is dispatched.
data.RunDispatcher();
}
// Dispatcher has exited.
Console.WriteLine("Shutdown.");
}
private static void DoOperations(object objData)
{
ThreadData data = (ThreadData)objData;
try
{
// Start scheduling operations from child thread.
for (int i = 0; i < 5; ++i)
{
int t = Thread.CurrentThread.ManagedThreadId;
int n = i;
data.ExecuteTask(() => SayHello(t, n));
}
}
finally
{
// Child thread is done.
data.OnThreadCompleted();
}
}
private static void SayHello(int requestingThreadId, int operationNumber)
{
Console.WriteLine(
"Saying hello from thread {0} ({1}) on thread {2}.",
requestingThreadId,
operationNumber,
Thread.CurrentThread.ManagedThreadId);
}
private sealed class ThreadData : IDisposable
{
private readonly Dispatcher dispatcher;
private readonly TaskScheduler scheduler;
private readonly TaskFactory factory;
private readonly CountdownEvent countdownEvent;
// In this example, we initialize the countdown event with the total number
// of child threads so that we know when all threads are finished scheduling
// work.
public ThreadData(int threadCount)
{
this.dispatcher = Dispatcher.CurrentDispatcher;
SynchronizationContext context =
new DispatcherSynchronizationContext(this.dispatcher);
SynchronizationContext.SetSynchronizationContext(context);
this.scheduler = TaskScheduler.FromCurrentSynchronizationContext();
this.factory = new TaskFactory(this.scheduler);
this.countdownEvent = new CountdownEvent(threadCount);
}
// This method should be called by a child thread when it wants to invoke
// an operation back on the main dispatcher thread. This will block until
// the method is done executing.
public void ExecuteTask(Action action)
{
Task task = this.factory.StartNew(action);
task.Wait();
}
// This method should be called by threads when they are done
// scheduling work.
public void OnThreadCompleted()
{
bool allThreadsFinished = this.countdownEvent.Signal();
if (allThreadsFinished)
{
this.dispatcher.InvokeShutdown();
}
}
// This method should be called by the main thread so that it will begin
// processing the work scheduled by child threads. It will return when
// the dispatcher is shutdown.
public void RunDispatcher()
{
Dispatcher.Run();
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
// Dispose all IDisposable resources.
private void Dispose(bool disposing)
{
if (disposing)
{
this.countdownEvent.Dispose();
}
}
}
}
Sample output:
Starting...
Saying hello from thread 3 (0) on thread 1.
Saying hello from thread 4 (0) on thread 1.
Saying hello from thread 3 (1) on thread 1.
Saying hello from thread 4 (1) on thread 1.
Saying hello from thread 3 (2) on thread 1.
Saying hello from thread 4 (2) on thread 1.
Saying hello from thread 3 (3) on thread 1.
Saying hello from thread 4 (3) on thread 1.
Saying hello from thread 3 (4) on thread 1.
Saying hello from thread 4 (4) on thread 1.
Shutdown.
You could communicate with the original thread through a class such as
class Communicator
{
public static volatile bool CreatePlayer;
}
And in socket code, change the CreatePlayer variable. In the reciever code, check the variable and create a player. After that, set CreatePlayer to false. Similarly with other things. Be careful about manipulating one variable across two threads at the same time - for example, it may be better to have four booleans for CreatePlayer than to have an int NumPlayersToCreate so that both threads aren't trying to constantly access the same data. Of course, you'd have to profile and see. One final thing: make sure the variables changed across both threads are marked as volatile. This makes each thread access the data from main memory rather than keeping it in cache (otherwise, each thread wouldn't notice the data being changed in the other thread's cache).
Yes, this is not the most performant or elegant solution, but it is the simplest. I'm sure someone will suggest a something more involved; if you want, I can do that as well. However, you seem unfamiliar with multithreading, so I thought you'd want something straightforward to get started.
I've written a test of what I think should be a valid case for a deadlock. It appears that once the lock has been acquired by an instance of the a class, that instance doesn't need to re-acquire the lock anymore even if I explicitly try to call another method that should lock again.
Here is the class:
internal class Tester
{
private readonly object _sync = new object();
public Tester() { }
public void TestLock()
{
lock (_sync)
{
for (int i = 0; i < 10; i++)
{
Deadlock(i);
}
}
}
private void Deadlock(int i)
{
lock (_sync)
{
Trace.WriteLine(i + " no deadlock!");
}
}
}
Output:
0 no deadlock!
1 no deadlock!
2 no deadlock!
3 no deadlock!
4 no deadlock!
5 no deadlock!
6 no deadlock!
7 no deadlock!
8 no deadlock!
9 no deadlock!
I would have thought that this would cause a deadlock... can anybody shed some light on this?
Locks in .NET are reentrant. Only acquisitions from other threads are blocked. When the same thread locks the same object multiple times, it simply increments a counter, and decrements it when released. When the counter hits zero, the lock is actually released for access from other threads.
The Monitor, Mutex and ReaderWriterLock classes maintain locks that have thread affinity. The ReaderWriterLockSlim class lets you choose, it has a constructor that takes a LockRecursionPolicy value. Using LockRecursionPolicy.NoRecursion is an optimization, a fairly big one if your locking is really fine-grained.
The Semaphore class is a synchronization class that does not have any thread affinity. This code deadlocks reliably:
class Tester {
private Semaphore sem = new Semaphore(1, 1);
public void TestLock() {
sem.WaitOne();
for (int i = 0; i < 10; i++) Deadlock(i);
sem.Release();
}
private void Deadlock(int i) {
if (!sem.WaitOne(100)) Console.WriteLine("deadlock!");
else {
sem.Release();
Console.WriteLine("No deadlock!");
}
}
}
In general, the thread affine synchronization classes require two threads and two locks to deadlock. The standard pattern is for one thread to acquire locks A and B, for the other to acquire B and A. The order is important.
There are less obvious deadlocks scenarios around in .NET programming, induced by locks that you cannot see because they are built-in to the .NET framework code. A very classic one is for BackgroundWorker. You could write code in the UI thread that spins on the Busy property, waiting for the BGW to complete. That always deadlocks when the BGW has a RunWorkerCompleted event handler. It cannot run until the UI thread goes idle, the BGW's Busy property won't be false until the event handler finished running.
In your scenario, you have a lock within another lock. Once the code hits the nested lock in "Deadlock", the "lock(...)" code is essentially ignored because it has already acquired it in "TestLock".
Great source for threading: http://www.albahari.com/threading/part2.aspx.
Monitor moni = new Monitor();
Thread t = new Thread(() => moni.CurrUsage(nics,200));
t.Start();
I start a thread named 't' inside the 'Form1_Load' function. I have added a button. When click on that button the thread 't' should stop executing and create a new thread with these parameters.
Monitor moni = new Monitor();
Thread t = new Thread(() => moni.CurrUsage(nics,950));
t.Start();
I know in the form_load event i can use the
t.Abort();
By making t a member of the form, you can reference it later on in the button-click event handler.
Graceful Abort.
Although t.Abort() gets the job done, you might be left with half-processed data in the thread t. You can catch the ThreadAbortException in thread t to gracefully end processing.
Beware of overlap.
The second problem is that your thread might not have aborted yet while your new thread has started already. You can prevent that by calling t.Join() after calling t.Abort().
Hope this helps.
Make Thread t a private member of your form.
public partial class MainForm : Form
{
private Thread t;
}
One way is to make Thread t a global variable (place outside of Form_Load). Then it can be accessed and modified from any method in that class.
To instantiate the thread, use t = new Thread(.....
Before aborting the thread, make sure it is not null.
You need to make the Thread object accessable in both places that you need to access it.
In this case, making it a private varaible would work.
e.g.
public class MyClass
{
private Thread MyThread
{
get;
set;
}
private void myfunc1()
{
MyThread = new Thread(() => moni.CurrUsage(nics,200));
MyThread.Start();
}
private void myfunc2()
{
MyThread.Abort();
// I really need to wait until this thread has stopped...
MyThread.Join();
}
}
Adding to the already given answers:
Note that .Join() will block your current (UI) thread, leaving your application unresponsive to the user.
Just as another take: avoid using .Abort() by using a flag in your Monitor class to exit the task you are doing if possible. You can then still wait for .Join(), but you have full control of the state in the background thread.
public class Monitor
{
private bool _cancel = false;
public void Cancel()
{
_cancel = true;
}
public void CurrUsage(Nics nics, int n)
{
_cancel = false;
// ...
while (!_cancel)
{
// do some stuff
}
}
}
in your Form
private Monitor _monitor { get; set; }
private Thread _t;
public void Button_Click(...)
{
_monitor.Cancel()
_t.Join() // will return as your background thread has finished cleanly
_t = new Thread(() => _monitor.CurrUsage(nics,950));
t.Start();
}
As others have pointed out, all you need in order to call Abort is a reference to the thread (just like any other object in .NET).
However
You should seriously consider rethinking this approach. In general, calling Abort is discouraged, as it does not give the target thread sufficient opportunity to reach a stopping point. While it's sometimes appropriate (or the only option), it's almost always a better idea to ask the target thread to stop (usually through a volatile bool rather than forcing it like this.
For example,
public class ThreadClass
{
private volatile bool stopRequested;
private Thread thread;
public void Start()
{
stopRequested = false;
thread = new Thread(ThreadMethod);
thread.Start();
}
public void Stop()
{
stopRequested = true;
if(!thread.Join(5000)) thread.Abort(); // forcefully abort if not
// completed within 5 seconds
}
private void ThreadMethod()
{
}
}
Your code then goes into ThreadMethod. Within the method, periodically check the value of stopRequested. If it's true, perform whatever cleanup is necessary (if any) and gracefully return out of the thread. If the content is a loop, the general practice is to place the check at the start of the loop (assuming that the loop is sufficiently tight) and exit early if the value is true. The exact placement is really dependent upon the code, but the general idea is that it should be checked often enough to make the thread exit fairly quickly after it gets set, regardless of when that happens.