Thread-Safety Mutex vs Lock(Synchronization of .net)

Mutex

A Mutex works in much the same way as the lock statement (that we will look at in the Critical sections section below), so I won't harp on about it too much. But the main advantage the Mutex has over lock statements and theMonitor object is that it can work across multiple processes, which provides a computer-wide lock rather than application wide.

Sasha Goldshtein, the technical reviewer of this article, also stated that when using a Mutex, it will not work over Terminal Services.

Application Single Instance

One of the most common uses of a Mutex is, unsurprisingly, to ensure that only one instance of an application is actually running

Let's see some code. This code ensures a single instance of an application. Any new instance will wait 5 seconds (in case the currently running instance is in the process of closing) before assuming there is already a previous instance of the application running, and exiting.

using System;
using System.Threading;

namespace MutexTest
{
    class Program
    {
        //start out with un-owned mutex
        static Mutex mutex = new Mutex(false,"MutexTest");

        static void Main(string[] args)
        {
            //check to see if there is another instance, allow 5 secs
            //another instance may be in process of closing right now
            if(!mutex.WaitOne(TimeSpan.FromSeconds(5)))
            {
                Console.WriteLine("MutexTest already running! Exiting");
                return;
            }
            try
            {
                Console.WriteLine("MutexTest Started");
                Console.ReadLine();
            }
            finally
            {
                //release the mutx to allow, possible future instance to run
                mutex.ReleaseMutex();
            }
        }
    }

}

So if we start an instance of this app, we get the message text in the console window: 

"MutexTest Started" 
When we try and run another copy, we get the following (after a 5 second delay): 
"MutexTest already running! Exiting" 

 

Lock

 

by the use of the lockkeyword. Only one thread can lock the synchronizing object (syncLock, in this case) at a time. Any contending threads are blocked until the lock is released. And contending threads are held in a "ready queue", and will be given access on a first come first served basis.

Some people use lock(this) or lock(typeof(MyClass)) for the synchronization object. Which is a bad idea as both of these are publicly visible objects, so theoretically, an external entity could use them for synchronization and interfere with your threads, creating a multitude of interesting problems. So it's best to always use a private synchronization object.

I now want to briefly talk about the different ways in which you can lock  

 

Other ways of doing "Lock" job

MethodImpl.Synchronized attribute

he last method relies on the use of an attribute which you can use to adorn a method to say that it should be treated as synchronized. Let's see this: 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MethodImplSynchronizedTest
{
    /// <summary>
    /// This shows how to create a critical section
    /// using the System.Runtime.CompilerServices.MethodImplAttribute
    /// </summary>
    class Program
    {
        static int item1=54, item2=21;

        static void Main(string[] args)
        {
            //make a call to different method
            //as cant Synchronize Main method
            DoWork();
        }

        [System.Runtime.CompilerServices.MethodImpl
        (System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
        private static void DoWork()
        {
            if (item1 != 0)
                Console.WriteLine(item1 / item2);
            item2 = 0;
            Console.ReadLine();
        }
    }

}

This simple example shows that you can use System.Runtime.CompilerServices.MethodImplAttribute to mark a method as synchronized (critical section).

One thing to note is that if you lock a whole method, you are kind of missing the chance for better concurrent programming, as there will not be that much better performance than that of a single threaded model running the method. For this reason, you should try to keep the critical sections to be only around fields that need to be safe across multiple threads. So try and lock when you read/write to common fields.

Of course, there are some occasions where you may need to mark the entire method as a critical section, but this is your call. Just be aware that locks should generally be as small (granularity) as possible. 

 

SynchronizationAttribute

该属性可作用在一个类上描述。目的是为了同步上下文,一样可以达到同步代码的作用 。 

 

 

你可能感兴趣的:(thread)