Getting Started with multithreading

Source: Internet
Author: User
Tags thread class ticket

1. Multithreading Programming Required Knowledge

1.1 Concepts of processes and threads

When we open an application, the operating system assigns a process ID to the application, such as opening QQ, and you will see the QQ.exe process in the Task Manager's Process tab, such as:

A process can be understood as a piece of memory that contains some resources, and the operating system divides its work into different units through the process. An application can correspond to multiple processes.

A thread is an independent unit of execution in a process, and for the operating system, it makes the application work by dispatching a thread, and at least one thread in a process, which we make the thread the main thread. The relationship between threads and processes can be understood as: a thread is the execution unit of a process, the operating system makes the application work by dispatching a thread, and the process is a container for the thread, created by the operating system, and created by the thread during the execution of the process.

1.2 Scheduling of threads

It seems to be mentioned in the operating system's book, "Windows is a preemptive multi-threaded operating system." The reason for this is that it is preemptive, because a thread can be preempted at any time to dispatch another thread. The operating system assigns a priority level of 0-31 to each thread, and prioritizes high-priority threads to CPU execution.

Windows supports 7 relative thread priorities: Idle, Lowest, BelowNormal, Normal, AboveNormal, highest, and time-critical. Where normal is the default thread priority. A program can change the priority of a thread by setting its first attribute, which is of type ThreadPriority enumeration type, whose members include lowest, belownormal, Normal, AboveNormal and highest. The CLR retains idle and time-critical two priority for itself.

1.3 Threads are also divided into front and rear tables

Threads have foreground threads and background thread points. In one process, when all foreground threads stop running, the CLR forces the end of all the background threads that are still running, and these background threads are terminated directly without throwing any exceptions. The main thread will always be the foreground threads. We can use the tread class to create a foreground thread.

1 using System; 2 using System.Threading; 3  4 Namespace multithreading 1 5 {6     internal class program 7     {8         private static void Main (string[] args) 9         {10
   var backthread = new Thread (Worker), one             backthread.isbackground = true;12             backthread.start ();             Console.WriteLine ("Exit from main thread");             Console.readkey (),}16.         private static void Worker ()         {19             Thread.Sleep (+);             Console.WriteLine ("Exit from Background Thread");         }22     }23}

The above code first creates a thread object through the thread class and then sets the IsBackground property to indicate that the thread is a background thread. If you do not set this property, the foreground thread is the default. The Start method is then called, at which point the background thread executes the code of the worker function. So there are two threads in this program, one is the main thread that runs the main function, and the other is the background thread that runs the worker thread. The CLR will unconditionally terminate the running of the background thread after the foreground thread finishes executing, so in the preceding code, the main thread will continue to run if the background thread is started. When the main thread finishes executing, the CLR discovers that the main thread ends, terminates the background thread, and then ends the entire application, so the console statement in the worker function will not execute. So the result of the above code is that the console statement in the worker function is not run.

You can use the Join function to ensure that the main thread does not start running until the background thread finishes executing.

1 using System; 2 using System.Threading; 3  4 Namespace multithreading 1 5 {6     internal class program 7     {8         private static void Main (string[] args) 9         {10
   var backthread = new Thread (Worker), one             backthread.isbackground = true;12             backthread.start ();             Backthread.join ();             Console.WriteLine ("Exit from main thread");             Console.readkey ();         }17         static void Worker ()         {             thread.sleep (+);             Console.WriteLine ("Exit from Background Thread");         }23     } 24}

The above code calls the JOIN function to ensure that the main thread runs after the background threads are finished.

If your thread executes a method that requires parameters, you need to use the overloaded constructor of the new thread, Thread (Parameterizedthreadstart).

1 using System; 2 using System.Threading; 3  4 Namespace multithreading 1 5 {6     internal class program 7     {8         private static void Main (string[] args) 9         {10
   var backthread = new Thread (new Parameterizedthreadstart (Worker));             Backthread.isbackground = true;12             Backthread.start ("Helius");             backthread.join ();             Console.WriteLine ("Exit from main thread");             Console.readkey ();         }17         private static void Worker (Object data),         {             thread.sleep (+);             Console.WriteLine ($ "The parameter passed in is {data. ToString ()} ");         }23     }24}

The result of the execution is:

2. Threads container-thread pool

We've all created threads manually through the Thead class, but the creation and destruction of threads can take a lot of time, so manual operations can result in a performance penalty. Therefore, to avoid the loss caused by manually creating threads through thread. NET introduces a thread pool mechanism.

2.1 Thread Pool

A thread pool is a collection of threads to be used in an application that can be understood as a place to hold threads, a centralized way to facilitate the management of threads.

When the CLR initializes, there are no threads in the thread pool. Internally, the thread pool maintains an operation request queue, and when an application wants to perform an asynchronous operation, it needs to call the QueueUserWorkItem method to add the corresponding task to the thread pool's request queue. The code of the thread pool implementation is extracted from the queue and delegated to the thread in the thread pool to execute. If the thread pool does not have idle threads, the thread pool also creates a new thread to perform the extracted tasks. When thread pool threads complete a task, the thread is not destroyed, but is returned to the thread pool, waiting for another request to be responded to. The loss of performance is avoided because threads are not destroyed. Remember that thread constructor threads are background threads, and the default level is normal.

2.2 Multithreading with thread pool

To use threads from the thread pool, you need to call the static method ThreadPool.QueueUserWorkItem to specify the method that the thread will invoke, which has two overloaded versions:

public static bool QueueUserWorkItem (WaitCallback callBack);

public static bool QueueUserWorkItem (WaitCallback callback,object State)

These two methods are used to add a work first and an optional state data to the thread pool queue. The two methods are then returned immediately. The following example shows how to use the thread pool for multithreaded programming.

 1 using System; 2 using System.Threading; 3 4 Namespace Multithreading 2 5 {6 class program 7 {8 static void             Main (string[] args) 9 {Console.WriteLine ($ "Main thread Id={thread.currentthread.managedthreadid}"); 11 ThreadPool.QueueUserWorkItem (Callbackworkitem); ThreadPool.QueueUserWorkItem (Callbackworkitem, "work"); (Thread.Sleep); Console.WriteLine ("Main thread Exit"), Console.readkey (); 16}1 7 private static void Callbackworkitem (Object state) Console.WriteLine ("Thread pool threads start Execution"); 2 1 if (state! = NULL) $ {Console.WriteLine ($) thread pool threads Id={thread.currentthread.manag Edthreadid}, the parameter passed in is {state. ToString ()} ");}25 Else26 {Console.WriteLine ($) thread pool threads id={ Rrentthread.managedthreadid} ");}29}30}31} 

The result is:

2.3 Collaborative cancellation of thread pool threads

The. NET Framework provides a mode of canceling operations, which is collaborative. In order to cancel an operation, you must create a System.Threading.CancellationTokenSource object. Here's another example of using code to illustrate:

Using system;using system.threading;namespace multithreaded 3{internal class program {private static void Main (string[            ] args) {Console.WriteLine ("Main thread Run");            var cts = new CancellationTokenSource (); ThreadPool.QueueUserWorkItem (Callback, CTS.            Token);            Console.WriteLine ("Press ENTER to cancel operation");   (); Cts.            Cancel ();        Console.readkey ();            } private static void Callback (object state) {var token = (CancellationToken) state;            Console.WriteLine ("Start Counting");        Count (token, 1000); } private static void count (CancellationToken token, int count) {for (var i = 0; i < Count; I + +) {if (token.                    iscancellationrequested) {Console.WriteLine ("Count cancellation");                Return                } Console.WriteLine ($ "Count: {i}");            Thread.Sleep (300); }            Console.WriteLine ("Count Complete"); }    }}

The result is:

3. Thread synchronization

Thread synchronization count refers to multithreaded programs, in order to ensure that the latter thread, only wait for the former thread to complete before continuing execution. It's like waiting in line to buy a ticket in front of a person who doesn't have a ticket before the person behind it has to wait.

3.1 Problems in multi-threaded programs

Multithreading can access a shared resource at the same time, which destroys the data that is saved in the resource. In this case, only thread synchronization techniques can be used.

3.2 Using monitor objects for thread synchronization

Monitor objects ensure that threads have mutually exclusive access to shared resources, and C # provides simplified syntax through the lock keyword.

 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading; 6 using System.Threading.Tasks; 7 8 Namespace Thread Sync 9 {Ten class Program11 {$ private static int tickets = 100;13 Static Object gl Obalobj=new object (), and the static void Main (string[] args) is {. Thread thread1=new thread (Saleti CKETTHREAD1); thread thread2=new thread (SaleTicketThread2); Thread1. Start (); thread2.             Start (); Console.readkey ();}22 all private static void SaleTicketThread2 () 24 {25 while (true) try28 {Monitor.Enter (glob                         Alobj); Thread.Sleep (1), if (Tickets > 0) 32 {33 Console.WriteLine ($ "Thread 2 ticket: {tickets--}");}35 Else36                     {PNS break;38}39}40 CATC                 H (Exception) throw;43}44 finally45  {Monitor.Exit (globalobj);}48}49}50 Wuyi Private                 static void SaleTicketThread1 () (). {Monitor.Enter (globalobj), Thread.Sleep (1);                     Ickets > 0) {Console.WriteLine ($ "Thread 1 ticket: {tickets--}"); 62                 }63 else64 {break;66}67                 }68 catch (Exception) throw;71}72 finally73                 {Monitor.Exit (globalobj); 75}76}77}78}7 9}

In the above code, an additional static global variable globalobj is first defined and passed as a parameter to the Enter method. Objects that are locked with monitor need to be reference types, not value types. Because when a value type is passed to enter, it is boxed into a separate poison fragrance before being passed to the Enter method, and a separate reference object is created when the variable is passed to the exit method. In this case, the object passed to the Enter method differs from the object passed to the exit method, and monitor throws an SynchronizationLockException exception.

3.3 Problems with thread synchronization technology

(1) Use more cumbersome. It is not possible to omit data that is accessed concurrently by multiple threads with extra code.

(2) Using thread synchronization can affect program performance. Because it takes time to acquire and release a sync lock, and to determine when the line enters upgradeable acquires a lock, the CPU also coordinates. These additional tasks will have a performance impact.

(3) thread synchronization allows only one thread to access resources at a time, which can cause a thread to clog. The system will then create more threads, and the CPU will be burdened with more onerous scheduling. This process can have an impact on performance.

The following is the code to explain the performance gap:

1 using System; 2 using System.Collections.Generic; 3 using System.Diagnostics; 4 using System.Linq; 5 using System.Text; 6 using System.Threading; 7 using System.Threading.Tasks; 8  9 Namespace thread synchronization X. {One     class Program12     {         static void Main (string[] args)         {             int x = 0;16             const int iterationnumber = 5000000;17             Stopwatch stopwatch=stopwatch.startnew (); (             int i = 0; i < Iterationnumber; i++).             {                 x++;21             }22             Console.WriteLine ($ "time spent without a lock: {stopwatch. Elapsedmilliseconds}ms ");             stopwatch. Restart (); (             int i = 0; i < Iterationnumber; i++) (+                 interlocked.increment (ref x);             }28             Console.WriteLine ($ "time spent using a lock: {stopwatch. Elapsedmilliseconds}ms ");             Console.readkey ();         }31     }32}

Execution Result:

Getting Started with multithreading

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: 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.