Multi-thread synchronization

Source: Internet
Author: User

One advantage of using multiple threads in an application is that each thread can be executed asynchronously. For Windows applications, time-consuming tasks can be executed in the background, so that the application windows and controls remain responsive. For server applications, multithreading allows different threads to process each incoming request. Otherwise, each new request cannot be processed until the previous request is fully satisfied.

However, the asynchronous nature of threads means that access to resources (such as file handles, network connections, and memory) must be coordinated. Otherwise, two or more threads may access the same resource at the same time, and each thread does not know the operations of other threads. Unexpected data corruption occurs.

For simple operations on integer data types, you can use interlocked class members to implement thread synchronization. For all other data types and non-thread-Safe Resources, only the structures in this topic can be used to safely perform multi-threaded processing (from msdn ).

 

1: Lock keyword

LockKeywords can be used to ensure that the code block is executed without being interrupted by other threads. This is achieved by obtaining mutex locks for a given object during the code block operation.

LockStatement with keywordsLockIt has an object as a parameter, and there is a code block that can only be executed by one thread at a time after this parameter. For example:

C #
public void Function(){    System.Object lockThis = new System.Object();    lock(lockThis)    {        // Access thread-sensitive resources.    }}

ProvidedLockThe parameter of the keyword must be an object of the reference type, which is used to define the lock range. In the above example, the lock range is limited to this function because no reference to this object exists outside the function. Strictly speakingLockThe object is only used to uniquely identify resources shared by multiple threads, so it can be any class instance. However, in fact, this object usually indicates the resources that require thread synchronization. For example, if a container object is used by multiple threads, the container can be passed to lock, and the synchronization code block after lock will access the container. As long as other threads lock the container before accessing the container, access to the object will be synchronized securely.

Generally, it is best to avoid lockingPublicType or lock an object instance that is not controlled by the application. For example, if the instance can be publicly accessedLock (this)There may be problems because uncontrolled Code may also lock the object. This may cause a deadlock, that is, two or more threads are waiting to release the same object. For the same reason, locking public data types (compared to objects) may also cause problems. Locking a string is especially dangerous because the string is "Temporarily" by the Common Language Runtime Library (CLR ". This means that there is only one instance for any given string in the entire program, and the same object represents the text in all threads in all running application domains. Therefore, as long as a lock is placed on a string with the same content anywhere in the application process, all instances of the string in the application will be locked. Therefore, it is best to lock private or protected members that are not temporarily retained. Some classes provide members dedicated for locking. For example, the array type provides syncroot. Many Collection types are also availableSyncroot.

 

2: Monitor

AndLockSimilar to the keyword, the monitor prevents multiple threads from executing code blocks simultaneously. The enter method allows only one thread to continue executing the subsequent statements. All other threads will be blocked until the thread that executes the statement calls exit. This is usedLockThe same keyword. In fact,LockKeywords are implemented using the monitor class. For example:

C # copy code
lock(x){    DoSomething();}

This is equivalent:

C # copy code
System.Object obj = (System.Object)x;System.Threading.Monitor.Enter(obj);try{    DoSomething();}finally{    System.Threading.Monitor.Exit(obj);}

UseLockKeyword is usually better than direct useMonitorClass is more desirable, on the one hand, becauseLockMore concise, on the other hand, becauseLockThis ensures that the basic monitor can be released even if the protected code causes an exception. This is throughFinallyKeyword, whether or not an exception is thrown, it executes the associated code block.

For more information about the monitor, see the monitor synchronization technical example.

Synchronization event and wait handle

The use of locks or monitors is useful to prevent simultaneous execution of code blocks that distinguish threads, but these constructs do not allow one thread to send events to another thread. This requires a "synchronization event", which is an object in two States (termination and non-termination) and can be used to activate and suspend threads. Enables a thread to wait for non-terminated synchronization events to suspend the thread, and changes the event status to terminate to activate the thread. If the thread tries to wait for the terminated event, the thread continues to execute without delay.

There are two types of synchronization events: autoresetevent and manualresetevent. The only difference between them is that wheneverAutoreseteventActivates a thread and its status will automatically change from terminating to non-terminating. On the contrary,ManualreseteventAllows its termination status to activate any number of threads. It is restored to a non-terminating State only when its reset method is called.

A thread can wait for an event by calling a wait method, such as waitone, waitany, or waitall. System. threading. waithandle. waitone enables the thread to wait until a single event changes to the terminated state. system. threading. waithandle. waitany stops the thread until one or more indicated events change to the terminated state. system. threading. waithandle. waitall stops the thread until all indicated events change to the terminated state. When the Set Method of the event is called, the event changes to the terminated state.

In the following example, a thread is created andMainFunction to start this thread. New thread usageWaitoneMethod to wait for an event. This event is executedMainThe main thread of the function is suspended until it is terminated. Once the event is terminated, the secondary thread returns. In this example, because the event is only used for the activation of one threadAutoreseteventOrManualreseteventClass.

C # copy code
using System;using System.Threading;class ThreadingExample{    static AutoResetEvent autoEvent;    static void DoWork()    {        Console.WriteLine("   worker thread started, now waiting on event...");        autoEvent.WaitOne();        Console.WriteLine("   worker thread reactivated, now exiting...");    }    static void Main()    {        autoEvent = new AutoResetEvent(false);        Console.WriteLine("main thread starting worker thread...");        Thread t = new Thread(DoWork);        t.Start();        Console.WriteLine("main thrad sleeping for 1 second...");        Thread.Sleep(1000);        Console.WriteLine("main thread signaling worker thread...");        autoEvent.Set();    }}

3: mutex object

Mutex is similar to monitor; it prevents multiple threads from executing a code block at a time. In fact, the name "mutex" is short for the term "mutually exclusive. However, unlike the monitor, mutex can be used to synchronize threads across processes. Mutex is represented by the mutex class.

When used for inter-process synchronization, mutex is called "named mutex" because it will be used for another application, so it cannot be shared through global variables or static variables. You must specify a name for the object to allow the two applications to access the same mutex object.

Although mutex can be used for intra-process thread synchronizationMonitorGenerally, it is more desirable because the monitor is designed specifically for the. NET Framework, so it can make better use of resources. In contrast,MutexClasses are the packages constructed by Win32. Although mutex is more powerful than the monitorMonitorClass, which consumes more computing resources. For examples of mutex usage, see mutex.

C #
private Mutex mutF = new Mutex();
private void ReadF()  
{  
    mutF.WaitOne();  
   // your code to access the resource              
    mutF.ReleaseMutex();  
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.