Question

I am constructing several objects from a Class and using a particular function from these classes to start Threads. Now the Class containing the member function from where these objects are constructed, has a static private Mutex member. I am passing this static member to the constructors and inside each constructor, the passed Mutex(presumably by reference) is assigned to another local member.

If I then use each of these local Mutex member to ensure Thread safety, will I be able to achieve this? I am counting on the fact, no matter how many different instances of the object containing the Thread function exists, since they are all referring to the same Mutex object, Thread safety is ensure if properly used.

Please find below code snippet to represent the Idea:

Class ThreadClass
{
 private Mutex myCopyOfMutex;
public ThreadClass(Mutex _globalMutex)
{
 myCopyOfMutex = _globalMutex;
}
public ThreadFunction()
{

// Wait until it is safe to enter.
myCopyOfMutex.WaitOne();
// critical code

// Release the Mutex.
 myCopyOfMutex.ReleaseMutex();

}
}

Class MotherClass
{
  private static Mutex mut = new Mutex();

  ThreadClass one = new ThreadClass(mut); // first instance
  Threadclass two = new ThreadClass(mut); // second instance

// Assign the Thread function to run on separate Thread

}
Was it helpful?

Solution

Yes, it will work. No, it's not passed by reference.

There is an important difference between passing a reference and passing by reference.

When you pass a reference type to a method, it's normally passed as a reference:

SomeMethod(mutex);

To pass a parameter by reference, you use the ref keyword:

SomeMethod(ref mutex);

The parameter in the method signature also has to be declared using the ref keyword:

public void SomeMethod(ref Mutex mutex) {

Passing a variable by reference means that you pass a reference to the variable, not a copy of the reference that is contained in the variable. The method can then change the variable itself, not only the object that the reference points to.

In most cases, and also in this case, you should pass parameters in the regular way. Passing by reference is only done when you need it for a specific reason.

OTHER TIPS

yes mutex are passed by reference as they are class type not the struct type

(Answer completely rewritten, the old answer is at the bottom)

Usually, System.Threading.Mutex is used for interprocess communication. If you just want to synchronize your threads within the same process, using a full-weight Mutex is an overkill. You can use any object with a lock operator:

Class ThreadClass
{
    // static is important, this way the object is shared among all
    // class instances
    private static object myMutex = new object();

    public ThreadFunction()
    {
        // Wait until it is safe to enter.
        lock(myMutex)
        {
            // critical code
        }
        // the mutex is automatically released after leaving the block.
    }
}

Class MotherClass
{
    ThreadClass one = new ThreadClass(); // first instance
    Threadclass two = new ThreadClass(); // second instance

    // Assign the Thread function to run on separate Thread
}

The advantage of lock-approach is the possibility of early returns and exception safety (imagine what happens if the critical code throws an exception; but look at Eric Lippert's article about exceptions under lock).

If the whole method is critical, and there are no more critical methods in the class, you can do it even simpler:

Class ThreadClass
{
    [MethodImpl(MethodImplOptions.Synchronized)]
    public ThreadFunction()
    {
        // critical code
    }
}

Class MotherClass
{
    ThreadClass one = new ThreadClass(); // first instance
    Threadclass two = new ThreadClass(); // second instance

    // Assign the Thread function to run on separate Thread
}

(Old answer is kept here for consistency)

All class instances are passed by reference in C#. If your Mutex is a class (for example, it's System.Threading.Mutex), it will automatically be passed by reference.

Look here for more info.


Correction:
As @Guffa correctly states, you don't pass a class instance by reference, but a reference to a class instance by value (if not using ref keyword). For your purpose, it's almost the same, actually. The difference is that the changes in the passed reference are not visible outside the callee.

From your briefing, I assume you are using Mutex to synchronize shared resource access.

Mutex is a managed reference type which under cover uses unmanaged mutex from Win32. To answer your question, Yes it is a reference type.

But your question leads me to think two points

  1. Why you are worried about reference ?

My advice is that, If you are worried about same Mutex instance to be shared then go ahead and create a named Mutex ( check the constructor overload for Mutex). Undercover operating system will ensure the synchronized access for this named Mutex.

  1. Why you want the Mutex instance to be static ?

My advice here is that, static variables are allocated by the JIT in special heap associated with the AppDomain. This is called Loader heap. This loader heap never get garbage collected unless you unload/reload AppDomain. So my point here is that, if you are using Mutex as static member then you likely to end up holding lot of mutex handles.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top