Use Interlocked to perform atomic operations under multiple threads. Use lockless and non-blocking methods to determine the thread running status and interlocked multithreading.

Source: Internet
Author: User

Use Interlocked to perform atomic operations under multiple threads. Use lockless and non-blocking methods to determine the thread running status and interlocked multithreading.

Skillfully use the Interlocked methods to determine the running completion status of all threads without locking or blocking.

Last night, I read chapter 29th of clr via c # <primitive thread synchronization structure>. Although this book was not the first time I read it, I used to read it all along, I did not have a deep understanding, or even did not understand it. After my internship, I found that my knowledge was so superficial that many implementations could not be made. This hit me a lot, the Spring Festival is also coming, and a solid foundation is needed. What caught my attention is jeffrey's description in Chapter 29th: Using Interlocked, the code is very short and will never block any thread. The second phase uses thread pool threads for automatic scaling. Download the source code and analyze the example in the following book. The code is as follows:

Using System; using System. collections. generic; using System. linq; using System. net. http; using System. text; using System. threading; using System. threading. tasks; namespace vlr_via_cs {internal static class AsyncCoordinatorDemo {public static void Go () {const Int32 timeout = 50000; // Change to desired timeout MultiWebRequests act = new MultiWebRequests (timeout); Console. writeLine ("All operations initia Ted (Timeout = {0}). Hit <Enter> to cancel. ", (timeout = Timeout. Infinite )? "Infinite": (timeout. toString () + "ms"); Console. readLine (); act. cancel (); Console. writeLine (); Console. writeLine ("Hit enter to terminate. "); Console. readLine ();} private sealed class MultiWebRequests {// This helper class coordinates all the asynchronous operations private AsyncCoordinator m_ac = new AsyncCoordinator (); // Set of Web servers we want to query & their responses (Exception or Int32) private Dictionary <String, Object> m_servers = new Dictionary <String, Object> {{" http://cjjjs.com/ ", Null },{" http://cnblogs.com/ ", Null },{" http://www.jobbole.com/ ", Null }}; public MultiWebRequests (Int32 timeout = Timeout. infinite) {// Asynchronously initiate all the requests all at once var httpClient = new HttpClient (); foreach (var server in m_servers.Keys) {m_ac.AboutToBegin (1 ); // make sure to add three times first. If Sleep exists, run httpClient after calling this function. getByteArrayAsync (server ). continueWith (task => ComputeResult (server, task);} // Tell AsyncCoordinator that all operations have Been initiated and to call // AllDone when all operations complete, Cancel is called, or the timeout occurs m_ac.AllBegun (AllDone, timeout);} private void ComputeResult (String server, task <Byte []> task) {Object result; if (task. exception! = Null) {result = task. exception. innerException;} else {// Process I/O completion here on thread pool thread (s) // Put your own compute-intensive algorithm here... result = task. result. length; // This example just returns the length} // Save result (exception/sum) and indicate that 1 operation completed m_servers [server] = result; m_ac.JustEnded ();} // Calling this method indicates that the re Sults don't matter anymore public void Cancel () {m_ac.Cancel ();} // This method is called after all Web servers respond, // Cancel is called, or the timeout occurs private void AllDone (CoordinationStatus) {switch (status) {case CoordinationStatus. cancel: Console. writeLine ("Operation canceled. "); break; case CoordinationStatus. timeout: Console. writeLine ("Operation timed-out. "); break; ca Se CoordinationStatus. allDone: Console. writeLine ("Operation completed; results below:"); foreach (var server in m_servers) {Console. write ("{0}", server. key); Object result = server. value; if (result is Exception) {Console. writeLine ("failed due to {0 }. ", result. getType (). name);} else {Console. writeLine ("returned {0: N0} bytes. ", result) ;}} break ;}} private enum CoordinationStatus {AllDon E, Timeout, Cancel}; private sealed class AsyncCoordinator {private Int32 m_opCount = 1; // Decremented when AllBegun CILS JustEnded private Int32 m_statusReported = 0; // 0 = false, 1 = true private Action <CoordinationStatus> m_callback; private Timer m_timer; // This method MUST be called BEFORE initiating an operation public void AboutToBegin (Int32 opsToAdd = 1) {Interlocked. add (ref m_opCount, OpsToAdd);} // This method MUST be called AFTER an operations result has been processed public void JustEnded () {if (Interlocked. decrement (ref m_opCount) = 0) ReportStatus (CoordinationStatus. allDone);} // This method MUST be called AFTER initiating ALL operations public void AllBegun (Action <CoordinationStatus> callback, Int32 timeout = Timeout. infinite) {m_callback = callback; if (timeout! = Timeout. infinite) {// call the callback function at the specified time point (dueTime), and then call the callback function m_timer = new Timer (TimeExpired, null, timeout, timeout. infinite) ;}justended () ;}// process obsolete thread private void TimeExpired (Object o) {ReportStatus (CoordinationStatus. timeout);} public void Cancel () {if (m_callback = null) throw new InvalidOperationException ("Cancel cannot be called before AllBegun"); ReportStatus (Coordinatio NStatus. Cancel);} private void ReportStatus (CoordinationStatus status) {if (m_timer! = Null) {// If timer is still in play, kill it Timer timer = Interlocked. Exchange (ref m_timer, null); if (timer! = Null) timer. dispose ();} // If status has never been reported, report it; else ignore it if (Interlocked. exchange (ref m_statusReported, 1) = 0) m_callback (status) ;}} class Program {static void Main (string [] args) {AsyncCoordinatorDemo. go (); Console. read ();}}}

It is indeed a lockless operation. The Interlocked method is an atomic operation in the user mode. It targets the CPU, not the thread memory, and it is a spin wait, consuming CPU resources. After analyzing the AsyncCoordinator class, we mainly use the Interlocked Add method to count the number of threads in real time. Then, when a thread runs, we call the Decrement method of Interlocked to reduce the number of threads. If you pay attention to it, you will find that the Interlocked methods are used in most concurrent judgments, especially the compareexchange method in interlocked anything mode, except that the return values of the compareexchange and exchange methods are the original values of the ref type, all other methods return the changed values. Finally, we can use the AllBegun method to determine if all threads are finished, and then set the status variable m_statusReported to 1 to prevent status judgment.

This class is very good. When writing concurrency, I always worried about how to judge whether the concurrency is complete and didn't want to use blocking. This class is very good. Of course, it may need to be changed when applied to a specific project, but the basic model remains unchanged.

A little emotion: we need to explore the good things by ourselves. When we checked the producer consumer model, there were a lot of java code, and the idea didn't see a few C #, even if it was simple, although java can be changed to C #, I feel a little bit that C # has fewer technical stacks and resources.

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.