Synchronization and communication multi-threaded C #

C #, use the lock Monitor and control multiple threads use of resources, the most common problem is that producers and consumers multithreading classic example of synchronization and communication. Learn C # multithreaded synchronization and communication.

I, on the lock and Monitor

The lock can be a code segment is defined to be mutually exclusive (critical section), in a time period exclusive allows only one thread enters execution, while the other threads must wait. Format is defined as follows:

lock(expression) statement_block

 expression representing an object to be tracked, is often cited. In general, if you want to protect the instance of a class, the use of this; protected if a static variable (e.g., mutually exclusive code segment within a static method), using the class name on it. The statement_block is mutually exclusive code segment.

Monitor the threads share resources when used in a multi-threaded programs targeting the public. Monitor must be associated with a specific object.

Second, the producer and consumer issues

Suppose that two threads at the same time maintaining a queue, if a thread updates an element of the queue, and another thread gets an element from the queue, then we call the element update thread for producers, said the acquisition of thread elements for consumers.

1, the operation target

Copy the code
   /// <Summary>; 
    /// operated object 
    /// </ Summary>; 
    public class Counter 
    { 
        // update and read digital 
        Private int numberOfCounter; 
        // read executable flag, a deadlock can be prevented occurs 
        Private = BOOL readFlag to false; 
 
        public void the read () 
        { 
            // after locking, the other for the read to this read operation is complete 
            lock (the this) 
            { 
                // first followed flase behavior, enters the wait 
                IF (readFlag!) 
                { 
                    the try 
                    { 
                        // wait for entering read, write another thread 
                        Monitor.Wait (the this); 
                    }
                    the catch (Exception EX) 
                {
                    { 
                        Console.WriteLine (EX); 
                    } 
                } 
 
                Console.WriteLine ( "consumption (Get): {0}", numberOfCounter); 
 
                // reset complete consumption 
                readFlag = to false; 
                Monitor.Pulse (the this); 
            } 
        } 
 
        public the write void (int Number the) 
        { 
            // once locked, the other writes will wait this time write operation is complete 
            lock (the this) 
            { 
                // first readFlag as flase, skip written to run the following 
                // If you are currently reading, waiting to be read operation execution Monitor.Pulse 
                IF (readFlag) 
                    the try 
                    {
                        Monitor.Wait (the this); 
                    } 
                    the catch (Exception EX) 
                    { 
                        Console.WriteLine (EX); 
                    } 
                } 
                numberOfCounter = Number; 
                Console.WriteLine ( "Production (Update): {0}", numberOfCounter); 
 
                // reset, production has completed 
                readFlag = to true; 
 
                // wait for synchronization is accomplished by Pulse 
                Monitor.Pulse (the this); 
            } 
        } 
    }
Copy the code

2, producers and consumers

Copy the code
   /// <Summary>; 
    /// producer 
    /// </ Summary> 
    public class CounterWrite 
    { 
        Counter counter; 
        // number of producers producing 
        int. 1 Quantity =; 
 
        public CounterWrite (Counter Box, int Request) 
        { 
            // structure function 
            counter = Box; 
            Quantity = Request; 
        } 
 
        // update information producer to the operation target 
        public void the Write () 
        { 
            for (int I =. 1; I & lt; = Quantity; I ++) 
                counter.Write (I); 
        } 
    } 
 
    / // <the Summary> 
    /// consumer  
    /// </ summary>
    public class CounterRead 
    { 
        Counter counter; 
        // number of producers producing 
        int. 1 Quantity =; 
 
        public CounterRead (Counter Box, int Request) 
        { 
            // Constructors 
            counter = Box; 
            Quantity = Request; 
        } 
 
        // consumers to obtain the information from the operation target 
        void the Read public () 
        { 
            for (int I =. 1; I & lt; = Quantity; I ++) 
                counter.Read (); 
        } 
    }
Copy the code

3, thread operations

Copy the code
       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();
Copy the code

Counter lock by lock object reference, initial readFlag control thread 1 waits for the false reading: Monitor.Wait (this),
the thread 2 is written, and then change readFlag, then execute: Monitor.Pulse (this), in the notification queue thread the request object status has changed,
thread 1 lock this, perform a read operation, and then change readFlag, thread 1 and thread 2 interactive write operations to read.
At the same time because there are alternately updated and readFlag avoid a deadlock situation.

Guess you like

Origin www.cnblogs.com/dazix/p/11087841.html