Code examples for C # thread synchronization detailed description

Source: Internet
Author: User
This paper mainly introduces the knowledge of C # thread synchronization. Have a good reference value, follow the small series together to see it

Objective

When threads of a thread pool are blocked, line pool creates additional threads, while creating, destroying, and dispatching threads requires quite expensive memory resources, and many developers are accustomed to creating more threads when they see that their program threads are not doing anything useful, in order to build a scalable, responsive program, In the previous article, we introduced the C # asynchronous programming explanation

But asynchronous programming also has a very serious problem, if two different threads access the same variables and data, according to our asynchronous function implementation, it is impossible to have two threads simultaneously access the same data, this time we need thread synchronization. Thread synchronization can prevent data corruption when multiple threads access shared data at the same time, emphasizing the same concept because thread synchronization is essentially a timing issue.

Asynchronous and synchronous are relative, synchronization is sequential execution, execution of one after execution of the next, need to wait, coordinated operation. Asynchronous is independent of each other, in the process of waiting for an event to continue to do their own things, do not have to wait for the event to complete and then work. A thread is a way to implement Asynchrony. Async is the main thread that lets the calling method do not need to wait for another thread to finish synchronously, so that the main thread can Cheng Gan other things.

Primitive user-mode and kernel-mode constructs

Basic concepts

Primitives: Simple constructs that you can use in your code

User mode: The thread is coordinated by a special CPU instruction, and the operating system never detects that a thread is blocked on the construction of the primitive user mode.

Kernel mode: Provided by Windows itself, calls a function implemented by the kernel in the application's thread.

User mode constructs

Variable structure

The C # compiler, the JIT compiler, and the CPU all optimize the code to keep our intentions as far as possible, but from a multithreaded perspective, our intentions are not necessarily preserved, as illustrated below:

static void Main (string[] args) {Console.WriteLine ("Let the Worker function stop after 5s"); var t = new Thread (worker); T.start (); Thread.Sleep (5000); Stop = true; Console.ReadLine (); } private static bool stop = FALSE; private static void Worker (object obj) {int x = 0; while (!stop) {x + +;} Console.WriteLine ("Worker function Stop x={0}", x); }

If the compiler checks to stop to false, it generates code to enter an infinite loop and increments x in the loop, so the optimization loop is completed very quickly, but the compiler detects stop only once, not every time.

Example 2---Two threads simultaneous access:

Class Test {private static int m_flag = 0; private static int m_value = 0; public static void Thread1 (Object obj) {m_val UE = 5; M_flag = 1; } public static void Thread2 (Object obj) {if (M_flag = = 1) Console.WriteLine ("M_value = {0}", m_value);//multi-core CPU machine will only appear thread Sync issue public void Exec () {var thread1 = new Thread (Thread1); var thread2 = new Thread (Thread2); Thread1. Start (); Thread2. Start (); Console.ReadLine (); } }

When the program executes, the compiler must read the variables M_flag and m_value from RAM to the CPU registers, the RAM first passes the value of M_value 0,thread1 the value to 5, but Thread2 does not know that Thread2 still thinks the value is 0, This problem is generally more likely to occur on multicore CPUs, where more CPUs are needed and the chances of multiple threads accessing resources at the same time are greater.

Keyword volatile, which prevents some optimizations of the C # compiler, JTP compiler, and CPU execution, if used for variables, will not allow the field to be cached in the CPU register, ensuring that the field reads and writes in RAM.

Interlock Construction

Each method in the System.Threading.Interlocked class performs an atomic read and write operation, and any variable writes that precede the invocation of a interlocked method are executed before the Interlocked method call, and any variable read after the call is After reading.

The Interlocked method is mainly for static operation of the INT32 variable add, decrement, Compare, Exchange, Comparechange and other methods, but also accept the object, double and other types of parameters.

Atomic manipulation: An operation that is not interrupted by the thread scheduling mechanism, which, once started, runs until the end without any context switch (switching to another thread).

Code Demo:

Description: Asynchronously queries several Web servers through the Interlocked method and returns data at the same time, with the result being executed only once.

Escalation status type enum Coordinationstatus {Cancel, Timeout, alldone}

Class Asynccoordinator {//allbegun internally calls justended to decrement it private int _mopcount = 1;//0=false,1=true private int _mstatusrepo rted = 0; Private action<coordinationstatus> _mcallback; Private Timer _mtimer; Call public void Abouttobegin (int opstoadd = 1) before initiating an operation {Interlocked.add (ref _mopcount, Opstoadd);}//after processing the result of an operation call pub  LIC void justended () {if (Interlocked.decrement (ref _mopcount) = = 0) {reportstatus (coordinationstatus.alldone);} }//The method must call public void Allbegin (action<coordinationstatus> callback, int timeout = timeout.infinite) After all actions have been initiated {_MC Allback = callback; if (timeout! = timeout.infinite) {_mtimer = new Timer (timeexpired, NULL, timeout, timeout.infinite); Justended (); }} private void TimeExpired (object o) {reportstatus (coordinationstatus.timeout);} public void Cancel () {Reportstatus (C Oordinationstatus.cancel); private void Reportstatus (Coordinationstatus status) {//If the status has never been reported, report it, otherwise ignore it and call only once if (Interlocked.exchange (ref _ mstatusreported, 1) = = 0) {_MCAllback (status); }  } }

Class Multiwebrequest {//Helper classes are used to coordinate all asynchronous operations private Asynccoordinator _mac = new Asynccoordinator (); protected dictionary< string,object> _mservers = new Dictionary<string, object> {{"http://www.baidu.com", null},{"http://www". microsoft.com ", null},{" http://www.cctv.com ", null}, {" http://www.souhu.com ", null},{" http://www.sina.com ", null},{ "http://www.tencent.com", null}, {"http://www.youku.com", null}}; Private Stopwatch sp; public multiwebrequest (int timeout = timeout.infinite) {sp = new Stopwatch (); Sp. Start (); One-time initiated request via asynchronous var httpclient = new HttpClient (); foreach (var server in _mservers.keys) {_mac. Abouttobegin (1); HttpClient. Getbytearrayasync (server). ContinueWith (Task = Computeresult (server, Task)); } _mac. Allbegin (alldone,timeout); Console.WriteLine ("");} private void Computeresult (string server, task<byte[]> Task) {object result; Exception! = null) {result = task. Exception.innerexception; } else {//thread pool handles IO result = task. Result.length; }//Save the returned resultsLength _mservers[server] = result; _mac. Justended (); } public void Cancel () {_mac. Cancel (); } private void Alldone (Coordinationstatus status) {sp. Stop (); Console.WriteLine ("Response time total {0}", sp. Elapsed);  Switch (status) {case CoordinationStatus.Cancel:Console.WriteLine ("Action canceled"); Break  Case CoordinationStatus.AllDone:Console.WriteLine ("operation completed, the result of completion is as follows"); foreach (var server in _mservers) {Console.WriteLine ("{0}", server.  Key); Object result = Server.  Value; If (result is Exception) {Console.WriteLine ("Error cause {0}", result. GetType ().  Name);  } else {Console.WriteLine ("Returns the number of bytes: {0}", result); }} break;  Case CoordinationStatus.Timeout:Console.WriteLine ("Operation timeout"); Break Default:throw New ArgumentOutOfRangeException ("status", status, NULL); } } }

We highly recommend that you refer to the above code, I will often refer to this model when accessing the server.

Simple spin Lock

Class Someresource {private Simplespinlock S1 = new Simplespinlock (); public void Accessresource () {S1. Enter (); Once there is a thread to access the S1. Leave (); }} class Simplespinlock {private int _mresourceinuse; public void Enter () {while (true) {if (Interlocked.exchange (ref _ mresourceinuse,1) ==0)  return;}} public void Leave () {volatile.write (ref _mresourceinuse,1);}}

This is a simple implementation of a thread synchronization lock, the biggest problem is that there is a competitive situation will cause the thread "spin", which will waste the CPU's valuable time, the organization CPU do more work, so this spin lock should be used to protect those who execute very fast code.

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.