C # language-multi-thread lock system (1 ),

Source: Internet
Author: User
Tags mscorlib

C # language-multi-thread lock system (1 ),

Introduction

In multi-threaded development, thread synchronization cannot be avoided. This article briefly describes the lock system in net multithreading. Directory 1: lock and Monitor 1: Basic. 2: scope. 3: string lock. 4: monitor use 2: mutex 3: Semaphore 4: Conclusion 1: lock, Monitor1: the Basic Lock is the simplified Writing of the Monitor syntax sugar. Lock generates Monitor in IL. // ======= Example 1 ===== string obj = "helloworld"; lock (obj) {Console. writeLine (obj);} // lock IL will be compiled into the following code: bool isGetLock = false; Monitor. enter (obj, ref isGetLock); try {Console. writeLine (obj);} finally {if (isGetLock) {Monitor. exit (obj) ;}} the isGetLock parameter is newly added after Framework 4.0. To enable the program to determine under all circumstances whether it is necessary to release the lock. For example, Monitor. Enter cannot obtain the lock. Monitor. Enter can be of the lock value type. The new object is packed in the lock. 2: Scope 1: Lock can only be locked in the process and cannot be performed across processes. Ii. type lock. Copy the Code as follows: // ======= Example 2 ===== new Thread (new ThreadStart () ==>{ lock (typeof (int) {Thread. sleep (1, 10000); Console. writeLine ("Thread1 release ");}})). start (); Thread. sleep (1000); lock (typeof (int) {Console. writeLine ("Thread2 release");} Let's look at an example. // ======= Example 3 ==== Console. writeLine (DateTime. now); AppDomain appDomain1 = AppDomain. createDomain ("AppDomain1"); LockTest Worker1 = (LockTest) appDomain1.CreateInstanceAndUnwrap (Assembly. getExecutingAssembly (). fullName, "leleapplication1.locktest"); Worker1.Run (); AppDomain appDomain2 = AppDomain. createDomain ("AppDomain2"); LockTest Worker2 = (LockTest) appDomain2.CreateInstanceAndUnwrap (Sembly. getExecutingAssembly (). fullName, "leleapplication1.locktest"); Worker2.Run (); /// <summary> /// when cross-application domain boundary or remote access is required, the MarshalByRefObject must be inherited. /// </summary> public class LockTest: Export albyrefobject {public void Run () {lock (typeof (int) {Thread. sleep (1, 10000); Console. writeLine (AppDomain. currentDomain. friendlyName + ": Thread released," + DateTime. now) ;}} the first example shows that the lock type int is actually the same in T object. Therefore, use it with caution. The second example is as follows. A: When CLR is started, the System Domain and Shared Domain will be created, and the Default AppDomain will be created ). The system domain and shared domain are single-instance. There can be multiple program domains. In this example, we use the AppDomain. CreateDomain method to create one. B: Normally, the code in each program domain is isolated and does not affect each other. However, for some basic types, each application domain is reloaded, which is a waste and brings additional loss pressure. The smart CLR will load the MSCorLib. dll Assembly of some basic types such as Object, ValueType, Array, Enum, String, and Delegate to the shared domain during CLR startup. Each program domain uses a basic instance of the shared domain. C: each application domain has its own hosting heap. GC heap and Loader heap are the most important items in the managed heap. GC heap is used for reference-type Instance Storage, lifecycle management, and garbage collection. Loader heap Storage System, such as MethodTable and data structure. The lifecycle of Loader heap is not managed by GC, and is related to uninstalling the program domain. So the int instance in the shared domain Loader heap MSCorLib. dll will be retained until the process ends. Uninstalling a single program domain is not affected. Very large scope !!! The second example is easy to understand. The lock int instance is cross-program domain, and the basic types in MSCorLib are all like this. It is easy to cause deadlocks and should be used with caution. The custom type is loaded into your own program domain and will not affect others. 3: We all know the purpose of the string lock, which is to destroy the multi-threaded value. We also know that string is a special object in c # And the value remains unchanged. Each change is a new object value, which is also the reason why stringbuilder is recommended. For Example: // ====== Example 4 ==== string str1 = "mushroom"; string str2 = "mushroom"; var result1 = object. referenceEquals (str1, str2); var result2 = object. referenceEquals (str1, "mushroom"); Console. writeLine (result1 + "-" + result2);/* output * True-True */due to the character string in c, therefore, strings are not modified in multiple threads and are read-only. It exists in a hash table in the managed heap in the SystemDomain domain. Key is the address of the string object, and Value is the address of the string object. When the program domain needs a string, CLR first tries to find the corresponding Item based on the string hash code in this Hashtable. If it is found, the corresponding reference is directly returned. Otherwise, the string is created in the managed heap corresponding to SystemDomain, added to the hash table, and the reference is returned. Therefore, the life cycle of a string is based on the entire process and cross-AppDomain. 4: the usage of monitor introduces the usage of Wait, Pulse, and PulseAll. With Comments, you can directly read the code. Static string str = "mushroom"; static void Main (string [] args) {new Thread () => {bool isGetLock = false; Monitor. enter (str, ref isGetLock); try {Console. writeLine ("Thread1 first lock acquisition"); Thread. sleep (1, 5000); Console. writeLine ("Thread1 temporarily releases the lock and waits for other threads to release the notification signal. "); Monitor. Wait (str); Console. WriteLine (" Thread1 is notified, and the second lock is obtained. "); Thread. sleep (1000);} finally {if (isGetLock) {Monitor. exit (str); Console. writeLine ("Thread1 release lock ");}}}). start (); Thread. sleep (1000); new Thread () => {bool isGetLock = false; Monitor. enter (str, ref isGetLock); // wait until other instances are released. Try {Console. WriteLine ("Thread2 get lock"); Thread. Sleep (5000); Monitor. Pulse (str); // notify a Thread in the queue to change the lock status. Pulseall notifies all Console. WriteLine ("Thread2 notifies other threads and changes the status. "); Thread. sleep (1000);} finally {if (isGetLock) {Monitor. exit (str); Console. writeLine ("Thread2 release lock ");}}}). start (); Console. readLine (); 2: mutex lock cannot be used across process locks. Mutex is similar to lock and can implement cross-process locks. Let's take a look at the example static bool createNew = false; // whether the first parameter should have the initial ownership of the mutex. That is, when createNew is true, mutex obtains the processing signal by default // The second is the name and the third is successful. Public static Mutex mutex = new Mutex (true, "mushroom. mutex ", out createNew); static void Main (string [] args) {// ===== Example 5 === = if (createNew) // when the first one is successfully created, the lock is obtained. No more WaitOne. Be sure to pay attention. {Try {Run () ;}finally {mutex. ReleaseMutex (); // release the current lock.} // The WaitOne function stops the current thread until it receives the processing signal released by another instance. // The first parameter is the wait time-out time, and the second parameter is whether to exit the context synchronization domain. Else if (mutex. waitOne (10000, false) // {try {Run ();} finally {mutex. releaseMutex () ;}} else // if no processing signal is found {Console. writeLine ("an instance already exists. "); Console. readLine () ;}} static void Run () {Console. writeLine ("instance 1"); Console. readLine ();} starts the test of instance a B in sequence. A gets the lock first and outputs instance 1. B is waiting. If A is released within 10 seconds, B gets the execution Run (). An instance is output after the timeout. Note that the first instance that obtains the processing signal has obtained the lock. No more WaitOne. Otherwise, an exception is reported. 3. Semaphore is the Semaphore. we can regard it as an upgraded mutex. Mutex locks a resource, while semaphore locks multiple resources. Semaphore has a thread counter. Each time a thread calls a counter, the counter is reduced by one. After the counter is released, the corresponding thread counter is added by one. The number of threads is exceeded. Semaphore can also be used across processes. Static void Main (string [] args) {Console. writeLine ("prepare for processing queue"); bool createNew = false; SemaphoreSecurity ss = new SemaphoreSecurity (); // Semaphore semaphore Semaphore = new Semaphore (2, 2, "mushroom. semaphore ", out createNew, null); for (int I = 1; I <= 5; I ++) {new Thread (arg) => {semaphore. waitOne (); Console. writeLine (arg + "processing"); Thread. sleep (10000); semaphore. release (); // semaphore. release (1) // Semaphore. Release (5); multiple instances can be released, but cannot exceed the maximum value. If the total number of last releases exceeds the total number, an error is returned. It is not recommended to use}). Start (I);} Console. ReadLine ();} 4: Conclusion: mutex and Semaphore have poor performance and need to be used again when cross-process is required. The performance of lock and Monitor is better. Pay attention to deadlocks.

Related Article

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.