C # Programming Summary (ii) Multithreading basics
Whether you are developing for a computer with a single processor or for a computer with multiple processors, you want the application to provide the user with the best response performance, even if the application is currently doing other work. One of the most powerful ways to enable applications to respond quickly to user actions while leveraging a processor between user events or even during user events is to use multithreaded technology.
Multithreading: A thread is a single sequential control flow in a program. Running multiple threads at the same time in a single program accomplishes different tasks, called multithreading. If a thread performs a long delay operation, the processor switches to another thread to execute. In this way, parallel (concurrent) execution of multiple threads hides long latencies, improving processor resource utilization and thus improving overall performance. Multithreading is to complete a number of tasks synchronously, not to improve the efficiency of the operation, but to improve the efficiency of the use of resources to improve the efficiency of the system
one, process and thread
process , is the operating system for resource scheduling and allocation of the basic unit. is composed of the process Control block, the program section, the data section three parts. A process can contain several threads (thread), and the thread can help the application do several things at the same time (such as one thread writing to the disk, the other receiving the user's keystrokes and reacting in a timely manner, without interfering with each other), after the program is run, The first thing the system needs to do is to create a default thread for the program process, and then the program can add or remove related threads on its own. It is a program that can be executed concurrently. The running process on a data set is an independent unit of system resource allocation and scheduling, also called activity, path or task, it has two aspects: activity, concurrency. Processes can be divided into three states of operation, blocking, readiness, and transforming with certain conditions: ready-run, run-block, block-ready.
Thread , the thread is the smallest unit of CPU scheduling and execution. Sometimes called a lightweight process (lightweight PROCESS,LWP), is the smallest unit of program execution flow. A standard thread consists of a thread ID, a current instruction pointer (PC), a collection of registers, and a stack. In addition, the thread is an entity in the process, is the basic unit that is dispatched and dispatched independently by the system, the thread itself does not own the system resources, and only has a bit of resources that are essential in the operation, but it can share all the resources owned by the process with other threads belonging to one process. One thread can create and revoke another thread, which can be executed concurrently between multiple threads in the same process. Because of the mutual constraints between threads, the thread is running in a discontinuous. Threads also have three basic states of readiness, blocking, and running.
The main thread, when the process is created, creates one by default, which is the main thread. The main thread is the threads that produce the other child threads, and the main thread must be the last one to end the execution, which completes various actions to close other sub-threads. Although the main thread is created automatically at the beginning of the program, it can also be controlled by the Thead class object, and the current thread's reference is obtained by calling the CurrentThread method
Multi-Threading Advantage : The process has a separate address space, and the thread in the same process shares the process's address space. Starting a thread is much less than the space it takes to start a process, and the time it takes to switch between threads is much less than the time it takes to switch between processes.
second, the advantages of multithreading
1. Improve application response. This is especially meaningful to the graphical interface program, when an operation takes a long time, the entire system waits for this operation, the program does not respond to the keyboard, mouse, menu operation, and the use of multi-threading technology, the time-consuming operation (consuming) into a new thread, can avoid this embarrassing situation.
2, make multi-CPU system more effective. The operating system guarantees that when the number of threads is not greater than the number of CPUs, different threads run on different CPUs.
3, improve the program structure. A long and complex process can be considered to be divided into multiple threads and become several separate or semi-independent parts of the run, which can be beneficial for understanding and modifying.
Although the advantages of multithreading are obvious, thread concurrency conflict, synchronization, and management tracing can bring a lot of uncertainties to the system, which must be paid enough attention to.
Don't say much nonsense to start our multi-threaded tour.
Three, multi-threaded application occasions:
Briefly summed up, there are generally two kinds of situations:
1) Multiple threads, complete similar tasks, improve concurrency performance
2) A task has multiple independent steps, multiple threads execute each sub-task concurrently, improve the efficiency of task processing
Iv. Cases--porters
In our real life, we often see such scenes. There was a pile of cargo, and several porters were responsible for transporting the goods to the designated location. But the porter ability is different, someone can move more box, some people walk relatively slow, carry a trip time interval is relatively long. Porters, their respective handling, no succession, non-interference. How do we implement this scenario in a program?
Case Analysis:
This is the simplest practical case of multithreading. Each person is the equivalent of a thread that executes concurrently. Once the cargo has been transported, each thread stops automatically. The deadlock situation is not considered here for the time being.
Case code:
Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading;namespace mutithreadsample.transport{//<summary>//Porter///</summary> public class Mover {// /<summary>///Total///</summary> public static int Goodstotal {get; set;} <summary>///Interval time///</summary> public static int IntervalTime {get; set;} <summary>/////</summary> public string name {get; set;} <summary>//unit time handling capacity///</summary> public int Laboramount {get; set;} <summary>///transport//</summary> public void Move () {while (Goodsto Tal > 0) {goodstotal-= Laboramount; Console.WriteLine ("Carrier: {0} transporting goods {2} at {1}", This.name,datetime.now.millisecond,this.laboramouNT); Thread.Sleep (IntervalTime); Console.WriteLine ("Carrier: {0} Continue", this. Name); }}///<summary>//handling//</summary>/<param name= "Interval" > Time Interval </param> public void Move (object interval) {int tempinterval = 0; if (!int. TryParse (interval. ToString (), out Tempinterval)) {tempinterval = IntervalTime; } while (Goodstotal > 0) {goodstotal-= Laboramount; Console.WriteLine ("Carrier: {0} carrying goods {2} at {1}", this. Name, DateTime.Now.Millisecond, this. Laboramount); Thread.Sleep (Tempinterval); } } }}
Test:
Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading;namespace mutithreadsample.transport{//<summary>///test handling//</summary> public class Testmove { <summary>///transport//</summary> public static void Move () {//Test move Shipping mover.goodstotal = 200; Mover.intervaltime = 10; Mover m1 = new Mover () {Name = "Tom", Laboramount = 5}; Mover m2 = new Mover () {Name = "Jim", Laboramount = 10}; Mover m3 = new Mover () {Name = "Lucy", Laboramount = 20}; list<mover> Movers = new list<mover> (); Movers. ADD (M1); Movers. Add (m2); Movers. Add (m3); if (movers! = NULL && movers. Count > 0) {foreach (Mover m in movers) { Thread thread = new Thread (new threAdstart (M.move)); Thread. Start (); }}//main Thread continue//Validate Thread.Sleep ()//int i = 0; int j = 0; while (I < ten)//{//while (j<10000000)//{//J + +; }//Console.WriteLine ("Currentthread:{0}", Thread.CurrentThread.Name); i++; }}///<summary>//handling//</summary> public static void Movewithparamt Hread () {//test Porter mover.goodstotal = 1000; Mover.intervaltime = 100; Mover m1 = new Mover () {Name = "Tom", Laboramount = 5}; Mover m2 = new Mover () {Name = "Jim", Laboramount = 10}; Mover m3 = new Mover () {Name = "Lucy", Laboramount = 20}; list<mover> Movers = new list<mover> (); MoVers. ADD (M1); Movers. Add (m2); Movers. Add (m3); if (movers! = NULL && movers. Count > 0) {foreach (Mover m in movers) {Thread thread = New Thread (New Parameterizedthreadstart (M.move)); Thread. Start (10); } } } }}
We've also touched thread through the case, and we'll cover the thread's functionality in detail below.
Five, Thread
Creates and controls a thread, sets its priority, and obtains its state.
Common methods:
Start ()
Causes the operating system to change the state of the current instance to threadstate.running.
Once the thread is in the threadstate.running state, the operating system can schedule its execution. The thread starts execution from the first line of the method (represented by the ThreadStart or Parameterizedthreadstart delegate provided to the thread constructor). Once the thread terminates, it cannot be restarted by calling start again.
Thread.Sleep ()
Calling the Thread.Sleep method causes the current thread to block immediately, and the length of the block time is equal to the number of milliseconds passed to Thread.Sleep, so that the remainder of its time slice is given to another thread. One thread cannot invoke Thread.Sleep on another thread.
Interrupt ()
Interrupts the thread that is in the WaitSleepJoin thread state.
Suspend and resume (obsolete)
Hang and Continue
In the. NET Framework version 2.0, the Thread.Suspend and Thread.Resume methods are marked as obsolete and will be removed from future releases.
Abort ()
method is used to permanently stop a managed thread. Once the thread is aborted, it cannot be restarted.
Join ()
Blocks the calling thread until a thread terminates.
ThreadPriority (Priority level)
Specifies the scheduling priority of the Thread.
ThreadPriority defines all possible values for a set of thread priorities. The thread priority specifies a line threads relative priority for another thread.
Each thread has a priority assigned to it. Threads created within the runtime are initially assigned the Normal priority, and threads created outside the runtime retain their previous priority when they enter the runtime. The priority property of the thread can be obtained and set by accessing it.
Schedules the execution of threads based on the priority of the thread. The scheduling algorithm used to determine the order of thread execution varies with the operating system. The operating system can also dynamically adjust the priority of a thread when the user interface's focus moves between the foreground and the background.
The priority of a thread does not affect the state of the thread, and the state of the thread must be Running before the operating system can dispatch the thread.
Vi. Creating threading methods
Through the Porter case we were able to understand how threading works and how threads were created.
In fact, there are several ways to create threads in C #, here are a few common examples, as follows:
Using system;using system.threading;namespace mutithreadsample{///<summary>//How to create threads///</summary& Gt Class CreateThread {//<summary>//delegate without parameters///</summary> public void creat Ethreadwiththreadstart () {Thread thread = new Thread (new ThreadStart (Threadcallback)); Thread. Start (); }///<summary>///For delegates with parameters///</summary> public void Createthreadwithparamthreads Tart () {Thread thread = new Thread (new Parameterizedthreadstart (Threadcallbackwithparam));
Object param = null; Thread. Start (param); }//<summary>///anonymous function///</summary> public void createthreadwithanonymousfunct Ion () {Thread thread = new Thread (delegate () {Console.WriteLine ("Enter sub-thread 1"); for (int i = 1; i < 4; ++i) {thread.sleep (50); Console.WriteLine ("\t+++++++ sub-thread 1+++++++++"); } Console.WriteLine ("Exit Sub-thread 1"); }); Thread. Start (); }//<summary>///Direct Assignment delegate///</summary> public void Createthreadwithcallback () {Thread _hthread = new Thread (threadcallback); _hthread.start (); }///<summary>///non-parametric method call///</summary> public void Threadcallback () { Do Something}//<summary> Method with parameters///</summary>//<param name= "obj" ></param> public void Threadcall Backwithparam (Object obj) {//Do Something}}}
Clock thread
Use the TimerCallback delegate to specify the method that you want the Timer to execute. The timer delegate is specified when the timer is constructed and cannot be changed. This method is not executed on the thread that created the timer, but on the system-supplied ThreadPool thread. When you create a timer, you can specify the amount of time to wait before the method is first executed (the cutoff time) and the amount of time to wait for the execution period thereafter (the time period). You can change these values or disable timers by using the changes method.
Using system;using system.threading;class timerexample{static void Main () {//Create an event to signal the Timeout count threshold in the//timer callback. AutoResetEvent autoevent = new AutoResetEvent (false); Statuschecker statuschecker = new Statuschecker (10); Create an inferred delegate this invokes methods for the timer. TimerCallback TCB = statuschecker.checkstatus; Create a timer that signals the delegate to invoke//CheckStatus after one second, and every the second thereafter. Console.WriteLine ("{0} Creating timer.\n", DateTime.Now.ToString ("h:mm:ss.fff")); Timer Statetimer = new Timer (TCB, autoevent, 1000, 250); When autoevent signals, change the period to every//second. Autoevent.waitone (n, false); Statetimer.change (0, 500); Console.WriteLine ("\nchanging period.\n"); When autoevent signals the second time, Dispose of//the timer. Autoevent.waitone (n, false); Statetimer.dispose (); Console.WriteLine ("\ndestroying timer."); }}class statuschecker{private int invokecount; private int maxCount; public Statuschecker (int count) {invokecount = 0; MaxCount = count; }//This method was called by the timer delegate. public void CheckStatus (Object stateInfo) {AutoResetEvent autoevent = (AutoResetEvent) stateInfo; Console.WriteLine ("{0} Checking status {}", DateTime.Now.ToString ("H:mm:ss.fff"), (++invokecou NT). ToString ()); if (Invokecount = = MaxCount) {//Reset the counter and signal Main. Invokecount = 0; Autoevent.set (); } }}
Vii. foreground thread and background thread
. The common language runtime (Common Language runtime,clr) of net can differentiate between two different types of threads: foreground and background threads. The difference between the two is that the application must run out of all foreground threads to exit, and for a background thread, the application can exit without considering whether it has finished running, and all background threads will automatically end when the application exits.
Whether a thread is a foreground thread or a background thread can be determined by its IsBackground property. This property is readable and writable. Its default value is False, which means that a line Cheng is considered a foreground thread.
We can set its IsBackground property to true so that it becomes a background thread. The following example is a console program in which the program starts with 10 threads and each thread runs for 5 seconds. Because the thread's IsBackground property defaults to False, which means that they are all foreground threads, the program's main thread runs out very quickly, but it will not end until all the threads that have started are finished running. The example code is shown in the following example, test ()
using system;using system.threading;namespace mutithreadsample.threadtype{class Threadtypetest {//&L t;summary>///test foreground thread///</summary> public static void Test () {for (int i = 0; I < 10; i++) {Thread thread = new Thread (new ThreadStart (ThreadFunc)); Thread. Start (); }}///<summary>//test background thread///</summary> public static void Testbackgrou Ndthread () {for (int i = 0; i <; i++) {Thread thread = new Thread (new ThreadStart (ThreadFunc)); Thread. IsBackground = true; Thread. Start (); }} public static void ThreadFunc () {thread.sleep (0); DateTime start = DateTime.Now; while ((Datetime.now-start). Seconds < 20);//Can pause for a long time, more obvious effect}}}
Next we make a slight modification to the above code to set the IsBackground property of each thread to true, and each thread is a background thread. So long as the main thread of the program is finished, the entire program is finished. Sample code such as Testbackgroundthread () in the code.
This example directly creates a console program to test.
Usage guidelines for foreground and background threads
Since foreground and background threads have this difference, how do we know how to set the IsBackground property of a thread? Here are some basic principles: for some threads running in the background, these threads should be set as background threads when the program ends without the need to continue running. For example, a program initiates a large number of operations of a thread, but as soon as the program is finished, the thread loses the meaning of the continuation, then the thread should be a background thread. Some threads that serve the user interface are often set up as foreground threads, because even if the program's main thread ends, other UI threads are likely to continue to exist to display the relevant information, so they cannot be terminated immediately. Here I just give some principles, specific to the actual use of the programmer will often require further careful consideration.
Viii. Summary
This chapter mainly introduces the basic knowledge of multithreading technology. Specific applications involving multithreading, including the prevention of deadlocks, threading synchronization, thread pooling, etc., will be covered in future articles.
C # Programming Summary (ii) Multithreading basics