Thread in C #-synchronization BASICS (synchronization nature, thread security, thread interruption)

Source: Internet
Author: User
Tags net thread

Content preview:

  • Thread entry (thread concept, thread creation)
  • Synchronization BASICS (synchronization nature, thread security, thread interruption,Thread status, synchronization Context)
  • Use threads (background tasks, thread pools, read/write locks, asynchronous proxies, timers, and local storage)
  • Advanced topic (non-blocking thread, support and recovery)

Nature of synchronization:The following list summarizes the. NET synchronization thread tools:

Blocking function:

  • Sleep: blocks a thread for a certain period of time.
  • Join: blocks another thread to this thread.

Lock Structure:

  • Lock: ensure that only one thread can access the same resource or operate a piece of code. Cross-process is not allowed. Fast.
  • Mutex: ensure that only one thread can access the same resource or operate a piece of code. It can be used to prevent a program from starting multiple threads. Cross-process, moderate speed.
  • Semaphore: ensure that a thread of no more than a certain number can access the same resource or operate a piece of code. Cross-process, moderate speed.

Signal structure:

  • Eventwaithandle: allows a thread to wait until it receives a signal from another thread. Cross-process, moderate speed.
  • Wait and pulse: Allow a thread to wait until a custom blocking occurs. Cross-process is not allowed. Average speed.

Non-blocking synchronization structure:

  • Interlocked: executes simple non-blocking atomic operations. Cross-process, fast.
  • Volatile: to allow secure non-blocking operations to access separate fields outside the lock. Cross-process, fast.

Blocking:

When we use the method mentioned above to suspend a thread, it is called to block the thread. Once the thread is blocked, a thread immediately gives itself the time allocated from the CPU, and adds waitsleepjoin to the threadstate attribute until it is no longer blocked. Blocking relief may be one of the following four methods (not press the power key ):

  • The blocking conditions are met.
  • Timeout
  • Interrupted by thread. Interrupt
  • Terminated by thread. Abort

A thread suspended through the suspend function will not be blocked.

Sleep and rotation:

Call thread. sleep to block the current thread (or wait until it is interrupted) for a given period of time ):

static void Main() {Thread.Sleep (0); // relinquish CPU time-sliceThread.Sleep (1000); // sleep for 1000 millisecondsThread.Sleep (TimeSpan.FromHours (1)); // sleep for 1 hourThread.Sleep (Timeout.Infinite); // sleep until interrupted}

More precisely, thread. Sleep returns control to the CPU. Thread. Sleep (0) means to give all the time slices to other active threads for execution. The thread class has a spinwait function, which does not discard any CPU time, but allows the CPU to cycle in the "invalid busy" for a specified number of times. 50 iterations are about one microsecond suspended. Technically speaking, spinwait is not a blocking method: A rotating-waiting thread no longer has the waitsleepjoin thread status and cannot be interrupted by other threads.

Spinwait is rarely used. It mainly aims to wait for a resource that can be quickly prepared (1 microsecond) without calling sleep and CPU switching threads. Although this technology can only be used on multi-core machines, there is no chance to rotate the time slice between threads on single-core machines. In addition, it is a waste of CPU time.

Blocking and rotation:

A thread can wait by explicitly polling: for example, while (! Proceed); or while (datetime. Now <nextstarttime); this operation is a waste of CPU time. In this case, the thread is not blocked, unlike the thread waiting for eventwaithandle. Variables are sometimes mixed between blocking and rotation:

while (!proceed) Thread.Sleep (x); // "Spin-Sleeping!"

The larger the value of X, the more CPU is used, which will increase the latency, but in addition to the latency, this method of combined rotation and sleep runs well.

Join a thread:

You can use join to block a thread until the end of another thread:

class JoinDemo {static void Main() {Thread t = new Thread (delegate() { Console.ReadLine(); });t.Start();t.Join(); // Wait until thread t finishesConsole.WriteLine ("Thread t's ReadLine complete!");}}

The join function receives a time-out function, in milliseconds, or a timespan. If time-out occurs, false is returned. The joint with time-out is similar to sleep. In fact, the following two lines of code are almost the same:

Thread.Sleep (1000);Thread.CurrentThread.Join (1000);

The semantic difference is that join means to keep the message pump active during blocking. Sleep pause the message pump.

Lock and thread security:

Only one thread can lock the synchronization object. If there are multiple threads, other threads will be in the queue state, and it is a first come, first served principle. The lock of C # is actually equivalent to the simplification of moniter. Enter and moniter. Leave in try/catch statements.

class ThreadSafe {static object locker = new object();static int val1, val2;static void Go() {lock (locker) {if (val2 != 0) Console.WriteLine (val1 / val2);val2 = 0;}}}

Equivalent

try {Monitor.Enter (locker);if (val2 != 0) Console.WriteLine (val1 / val2);val2 = 0;}finally { Monitor.Exit (locker); }

If you do not call monitor. Enter before you call monitor. Exit, an exception is thrown. Moniter also has a tryenter function that can specify a time-out period and enter the critical section after the current thread times out.

Select the synchronization object:The synchronization object must be of the reference type, regardless of the specific reference type.

Nested lock:The thread can repeatedly lock the same object, either through moniter. Enter or moniter. Leave.

static object x = new object();static void Main() {lock (x) {Console.WriteLine ("I have the lock");Nest();Console.WriteLine ("I still have the lock");}Here the lock is released.}static void Nest() {lock (x) {...}Released the lock? Not quite!}

When to lock:A basic principle is that a field should be locked as long as multiple threads operate, even a simple value assignment operation.

Performance considerations:The lock operation itself is very fast, that is, a matter of several seconds, but the waiting time between threads may be very long. However, improper use may cause:

  • Concurrency is exhausted. When the code in the lock area is too long, other threads may wait too long.
  • Deadlock occurs when two threads wait for each other at the same time, but neither of them can continue execution. It is usually caused by too many synchronization objects.
  • Lock competition. When both threads may obtain a lock first, the program may get the lock due to the wrong thread.

Thread security:Thread-safe code is free of uncertainty in multi-thread scenarios. It mainly uses locks to reduce interaction between threads for the purpose.
A function is thread-safe in any situation. It can be reentrant. Generally, the type of objective is rarely thread-safe, because:

  • The development burden of ensuring full thread security is very heavy, because a class generally has many fields.
  • Thread security requires performance costs.
  • Thread-safe functions do not need to be used in thread-safe mode.

Thread security is generally required in multi-threaded scenarios. There are some ways to achieve thread security with a large and complex class.
One way is to include a large segment of code in an exclusive lock.
Another method is to reduce the interaction between threads by reducing the amount of shared data. This method performs well on stateless middleware and web servers, because multiple client requests may arrive at the same time, each request is in a separate thread (such as ASP.. net, WebService, etc.), then these requests must ensure thread security. Stateless design also limits the possibility of interaction between threads, because classes cannot store data in each request. The interaction between threads is limited to static fields, such as memory data shared by users and identity authentication services.

.Net thread security :.Almost all primitive types of. Net are not thread-safe. Thread-safe code can be converted into thread-safe code through lock.

class ThreadSafe {static List <string> list = new List <string>();static void Main() {new Thread (AddItems).Start();new Thread (AddItems).Start();}static void AddItems() {for (int i = 0; i < 100; i++)lock (list)list.Add ("Item " + list.Count);string[] items;lock (list) items = list.ToArray();foreach (string s in items) Console.WriteLine (s);}}

Here we lock the List itself. This is acceptable. If there are two lists that interact with each other, we should lock a general object.
It is not thread-safe to enumerate the list and convert it into an array. Any operation that may modify the list is not thread-safe.
Static members are thread-safe in. net, but the instance members are not.

Thread interrupt and abort:You can use thread. Interrupt and thread. Abort to interrupt and abort a thread, but only the active thread can operate. The waiting thread is powerless.

Call interrupt to force release a thread and throw a thread interruption exception:

class Program {static void Main() {Thread t = new Thread (delegate() {try {Thread.Sleep (Timeout.Infinite);}catch (ThreadInterruptedException) {Console.Write ("Forcibly ");}Console.WriteLine ("Woken!");});t.Start();t.Interrupt();}}

Output: forcibly woken!

An Interrupted thread will only release the thread from the current time slice and wait for it to enter the next time slice, but will not terminate. Unless threadinterruptedexception is not handled.
If interrupt is called on a thread without locks, the thread continues to execute until the time slice ends.

It is dangerous to interrupt a thread at will, because. Net or third-party functions may be unexpectedly interrupted in the call stack, so what you need is to lock and wait or synchronize resources. If the function is not designed and can be interrupted, it may cause Insecure code and incomplete release of resources. Unless you explicitly know all the details of the thread.

You can use thread. Abort to forcibly release the time slice of a thread.The effect is similar to interrupt, but the threadabortexception exception must be handled here. This exception will be thrown again at the end of the Catch Block unless thread is executed in the catch. resetabort. the thread status changes to abortrequested.

The biggest difference between interrupt and abort is the result of downgrading when the thread is not blocked. Interrupt will continue execution before the next time slice arrives, and abort will throw an exception. Abort a non-blocking thread may have some consequences, which will be discussed in detail later.

 

 

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.