C # multi-thread synchronization and communication

Source: Internet
Author: User

In C #, use lock and Monitor to control the use of resources by multiple threads. The most common producer and consumer problems are typical examples of multi-thread synchronization and communication. This article uses examples to understand the synchronization and communication of C # multithreading.

I. About lock and Monitor

Lock can define a piece of code as a critical section. A mutex can only allow one thread to enter the execution at a time point, while other threads must wait. The format is defined as follows:

lock(expression) statement_block

 

Expression indicates the object to be tracked, which is usually referenced. Generally, if you want to protect an instance of a class, use this; if you want to protect a static variable (such as a mutex code segment inside a static method), use the class name. Statement_block is the code of the mutex.

Monitor is used to share resources with threads when multiple threads share an object. Monitor must be associated with a specific object.

Ii. producer and consumer issues

Assume that two threads maintain a queue at the same time. If one thread updates the elements in the queue and the other thread obtains the elements from the queue, the thread that calls the updated element is the producer, the thread for retrieving elements is called the consumer.

1. objects to be operated

/// <Summary>; // the object to be operated /// </summary>; public class Counter {// update and read the number private int numberOfCounter; // The Read operation can be tagged to prevent deadlock. private bool readFlag = false; public void Read () {// After the lock, other read Operations wait for this read operation to complete lock (this) {// The first action flase, enter wait if (! ReadFlag) {try {// enter the waiting for read, and the other thread writes the Monitor. wait (this);} catch (Exception ex) {Console. writeLine (ex) ;}} Console. writeLine ("Consumption (obtained): {0}", numberOfCounter); // reset, consumption completed readFlag = false; Monitor. pulse (this) ;}} public void Write (int number) {// After the lock, other Write operations wait until this Write operation completes lock (this) {// The First Time readFlag is flase, skip the write below execution // if the current read is in progress, wait for the read operation to execute Monitor. pulse if (readFlag) {try {Monitor. wait (this);} catch (Exception ex) {Console. writeLine (ex) ;}} numberOfCounter = number; Console. writeLine ("production (update): {0}", numberOfCounter); // reset, production has completed readFlag = true; // synchronization completes Monitor by waiting for Pulse. pulse (this );}}}

2. producer and consumer

/// <Summary>; // producer /// </summary> public class CounterWrite {Counter counter; // number of producer production times int quantity = 1; public CounterWrite (Counter box, int request) {// constructor counter = box; quantity = request;} // The producer updates the public void Write () Information to the operation object () {for (int I = 1; I & lt; = quantity; I ++) counter. write (I) ;}//< summary> /// consumer // </summary> public class CounterRead {Counter counter; // producer production count int quantity = 1; public CounterRead (Counter box, int request) {// constructor counter = box; quantity = request ;} // The consumer obtains information from the operation object public void Read () {for (int I = 1; I & lt; = quantity; I ++) counter. read ();}}

3. Thread operations

Counter counter = new Counter();             CounterRead read = new CounterRead(counter, 10);            CounterWrite write = new CounterWrite(counter, 10);             Thread th1 = new Thread(new ThreadStart(read.Read));            Thread th2 = new Thread(new ThreadStart(write.Write));             th1.Start();            th2.Start();             th1.Join();            th2.Join();             Console.ReadLine();

Lock the reference of the Counter object, and the initial readFlag is false to control thread 1 waiting for reading: Monitor. wait (this), thread 2 writes, then changes readFlag, and then executes: Monitor. pulse (this), notifies the waiting queue that the thread request object status has changed, thread 1 locks this, executes the read operation, and then changes readFlag, thread 1 interacts with thread 2 to execute write and read operations.

At the same time, because of the existence of readFlag and alternate updates, the deadlock situation is avoided.

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.