Multithreaded programming learning notes-thread synchronization (i)

Source: Internet
Author: User
Tags mutex semaphore

Take the multithreaded Programming learning note above-Foundation (i) Take the multithreaded Programming learning note above-Basic (ii) Take the multithreaded Programming learning note above-Basic (iii)

As in the previous article ( multithreaded Programming Learning Note-Basic (c)), example code 10, as if multithreading uses shared variables, involves a thread synchronization problem. How to solve it?

There are three methods:

1) Refactor the program, remove multi-threaded shared variables, and let a thread access only one of its own variables

2) with atomic operations, an operation takes only one quantum time, one completion, and only when the current operation is complete, other threads can operate. This avoids the use of exclusive locks and avoids deadlocks.

3) through the NET Framework provided by the mutex, Autorestevent, Countdowneven, spinwait and other classes, to synchronize between threads.


first, the use of interlocked class

In the previous article, we used lock to solve the question of multi-threaded access, and here we use atomic operations provided by the Interlocked class to help us avoid locking locks to prevent deadlocks.

Next we'll change the code in the previous article, as shown in the code below.

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading;//Introducing ThreadsusingSystem.Diagnostics;namespacethreadsynchronousdemo{classProgram {Static voidMain (string[] args) {Console.WriteLine ("start, interlocked sync"); varc =NewCounter (); Thread T=NewThread (() =Count (c)); varT3 =NewThread (() =Count (c)); vart2 =NewThread (() =Count (c)); T.name="Thread 1"; //Start ThreadT.start (); T2. Name="Thread 2"; T2.             Start (); T3. Name="Thread 3"; T3.            Start ();            T.join (); T2.            Join (); T3.            Join (); Console.WriteLine (string. Format ("multi-threaded total without locks: {0}", C.count)); Console.WriteLine ("----------------------------"); varC1 =Newcounterinterlocked (); varT4 =NewThread (() =Count (C1)); T4. Name="Thread 4"; varT5 =NewThread (() =Count (C1)); T5. Name="Thread 5"; varT6 =NewThread (() =Count (C1)); T6. Name="Thread 6"; T4.            Start (); T5.            Start (); T6.            Start (); T4.            Join (); T5.            Join (); T6.            Join (); Console.WriteLine (string. Format ("Multithreading totals for interlocked: {0}", C1.            Count));        Console.read (); }        Static voidCount (Countbase cnt) { for(inti =0; I <100000; i++) {cnt.                Incerement (); Cnt.            Dncerement (); }        }    }    Abstract classCountbase { Public Abstract voidincerement ();  Public Abstract voiddncerement (); }    classCounter:countbase { Public intCount {Get;Private Set; }  Public Override voiddncerement () {Count--; }         Public Override voidincerement () {Count++; }    }    classCounterinterlocked:countbase {Private intM_count;  Public intCount {Get{returnM_count;} }         Public Override voiddncerement () {interlocked.decrement (refm_count); }         Public Override voidincerement () {interlocked.increment (refm_count); }    }}

The results of this program run as follows in the previous article in Example 10, the result is the same. Just the difference in the code.

Ii. use of Mutex classes

1. Next, we'll learn to use mutex classes to implement synchronization between threads.

2. When the program starts, set Initialowner to False, which means that if the mutex is already established, the program is allowed to obtain a mutex amount. If there is no mutex, the program runs directly, waits for any key to be received, and then releases the mutex.

3. The code is as follows:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading;//Introducing ThreadsusingSystem.Diagnostics;namespacethreadsynchronousdemo{classProgram {Const stringMutexname ="Syncmutex"; Static voidMain (string[] args) {Console.WriteLine ("start, Mutex synchronization"); using(varmut=NewMutex (false, Mutexname)) {                if(!mut. WaitOne (Timespan.fromseconds (5),false) {Console.WriteLine ("wait 5 seconds to run .... "); }                Else{Console.WriteLine ("running .... , please enter any key");                    Console.ReadLine (); Mut.                    ReleaseMutex (); Console.WriteLine ("Release Mutex amount");        }} console.read (); }    }} 

4. Running results such as.

in the Debug directory , run the main program first, such as 1, then program 1 runs normally, if you open the debug directory under the application main program, then run the result as in 2. Indicates that the mutex has worked.

5. First enter K in main program 1, then enter, as shown in 3. We open the application from the debug directory again, then the application runs as in 4. Description of the main program 1, the mutex has been released.

Note: The named mutex is a global operating system object. Be sure to close the mutex correctly. It is best to use a using to wrap the mutex code. This way you can synchronize threads in different programs.

Third, the use of Semaphoreslim class

Semaphoreslim is a lightweight version of the Semaphore class. This class restricts the number of threads that concurrently access the same resource.

In. NET, class semaphore encapsulates a kernel synchronization object in the CLR. Unlike the standard exclusive lock object (Monitor,mutex,spinlock), it is not an exclusive lock object, which, like Semaphoreslim,readerwritelock, allows multiple limited threads to access shared memory resources at the same time.

Semaphore is like a fence, has a certain capacity, when the number of threads inside the set reaches the maximum value, there is no thread to go in. Then, if a thread comes out after the work is done, the next thread can go in. Semaphore, such as WaitOne or release, will automatically decrement or increment the current count value of the semaphore, respectively. When a thread attempts to perform a waitone operation on a semaphore that has a count value of 0, the thread blocks until the count value is greater than 0. When constructing a semaphore, you need at least 2 parameters. The initial capacity of the semaphore and the maximum capacity.

1. Program code

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading;//Introducing ThreadsusingSystem.Diagnostics;namespacethreadsynchronousdemo{classProgram {StaticSemaphoreslim Semapslim =NewSemaphoreslim (5); Static voidMain (string[] args) {Console.WriteLine ("start, Semaphoreslim sync");  for(inti =1; I <9; i++)            {                stringThreadName ="Threads"+i; intseconds =NewRandom (). Next (1,Ten); vart =NewThread (() =Accessdatabase (threadname, seconds));            T.start ();        } console.read (); }        Static voidAccessdatabase (stringNameintseconds) {Console.WriteLine ("{0} Waiting to Access database", name);            Semapslim.wait (); Console.WriteLine ("{0} was granted access to the database", name);            Thread.Sleep (timespan.fromseconds (seconds)); Console.WriteLine ("{0} has completed", name);                  Semapslim.release (); }    }}

2. Program operation results such as.

When the program starts, a Semaphoreslim object is created, the number of concurrent threads is specified in the constructor, and a thread with 10 different names, with different initial run times, is started.

Each thread tries to get access to the database, but we use the Semaphoreslim object to restrict it, only 5 threads can access the database at the same time, and after the current 5 threads have access to the database, the remaining 5 threads can wait until the thread is finished working. and call the release method of semaphore.

Multithreaded programming learning notes-thread synchronization (i)

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.