views:

571

answers:

2

I have several threads that acquire Mutexes and then terminate.

The mutexes are stored in a main repository, and are properly released when the program exists. However, when the thread that allocated a Mutex exists, the mutex gets released automatically, and subsequent acquire AbandonedMutexException (also according to the documentation).

How can I avoid this exception, and keep using a Mutex even after the allocating thread finished? Is there another, more appropriate synchronization construct in .Net that doesn't have this limitation.

Note - I am looking for a cross-process synch mechanism with similar semantics to Mutex.

A: 

Looks like EventWaitHandle does what I want. It has a constructor that takes a name, so it's perfect for cross-process synch, and it doesn't have this problem.

ripper234
+4  A: 

Response to the question

AFAIK there exist no such Mutex class. The AbandonedMutexException is quite annoying but it represents a real situation that can occur for which there is no automatic solution.

When you have cross process, or even cross thread communication, you must deal with the fact that any one of the participating entities can be unexpected and suddenly terminated for any number of reasons. Mutex's exist to protect resources, if a thread is abandoned while it holds a Mutex there is no way for the OS to guarantee that it left data in any consistent manner. This is very important because it means that the abandoning of the thread could have invalidated certain invariants being depended on by other threads.

The AbandonedMutexException is a way of proactively saying "bad things happened and you are now in an indeterminate state". There is really no other recoures for the operating system here.

Response to your answer

EventWaitHandle is different that Mutex and serves different purposes.

Mutex is used to protect a particular resource much like a lock statement. When a particular thread acquires a mutex it is said to own the Mutex. There can only be one owner at a time. So if all threads involved agree to only touch a resource when they have ownership of the Mutex, you can safely access a resource across thread.s

EventWaitHandle can be visualed, to a degree, as a thread safe event. It has the concept of signaled and unsignaled and any number of threads can wait for it to hit a signaled state. When it is signaled one of the waiting threads will be woken up and will start processing.

You can use an EventWaitHandle to implement a form of thread safety. Instead of lock ownership being the key to accessing the resource, being signaled from the event is the key to accessing the resource. However, the devil is once again in the details.

  1. Who is in charge of signaling the event? With a mutex, every thread is essentially screaming "me me me" and the OS picks one thread to win. With an EventWaitHandle you will be responsible for deciding when the next thread gets to go.
  2. What happens when someone kills a process via taskmgr? What if the process killed has a thread currently responding to an event on the EventWaitHandle?
  3. #2 but what happens when the item who gets to signal the wait handle next is taken down? You must account for this to avoid deadlock.
JaredPar
It turns out that for my purpose, a simple event was equally good (better because it didn't become abandoned). Thanks for the detailed answer.I do not have to decide "who gets to win" - the OS still decides which of two threads win an AutoResetEvent.Wait().
ripper234
@ripper234 but you do though. You are response for calling the Set method and thus deciding when the OS decides who wins.
JaredPar
Just like I'm responsible for releasing the mutex. For my purpose, I specifically did not want the OS to decide for me that the mutex should be released.
ripper234