CLR via C # -- thread

Source: Internet
Author: User
Thread Function

Early operating systems did not have the concept of "Thread". For example, a 16-bit Windows operating system does not support multithreading. such a system has a feature that the entire system only runs one task at a time, including the Operating SystemCodeApplicationsProgramThis brings about a problem: if the current running task takes a long time to complete, it will stop other tasks from being executed. If a program containsBugThe program entered an endless loop and the user had to restart the computer.

Such an operating system is obviously not powerful. Microsoft decided to improve the operating system kernel to improve its robustness, reliability, scalability, and security. microsoft began writing Windows NT in November 1988. When designing the system kernel, Microsoft decided to run every instance of the application in a process, A process is a collection of resources to be used by an instance of an application. each process is assigned a virtual address space to ensure that one process cannot access the code and data of another process. because one process cannot destroy the code and data of another process, the robustness of the system is improved; the program cannot access the username, password, and other information of another application, so the security is improved.

Although the data cannot be damaged and is safer, if an application enters an infinite loop and the machine has only one CPU, the CPU executes an infinite loop and the system stops responding. microsoft's solution to this problem is "Thread ".The role of a thread is to virtualize the CPU.Windows provides a dedicated thread for each process (it can be understood that the system allocates a CPU to each process, but it is virtual ), when this program enters an infinite loop, it will not affect the running of other programs. windows NT July 1993 launched in 3.1 is the first Windows operating system that supports multithreading.

Thread overhead

A thread is undoubtedly a good thing. It allows the operating system to respond to tasks that take a long time to complete, the thread also allows you to use the task manager to forcibly terminate applications that appear to have been frozen. but there is always a price for good things!

Thread Composition

Each part of a thread has certain functions. They are responsible for creating a thread, entering the operating system, and finally destroying it. They all require time and space.

1. Thread Kernel Object)Each thread has such a data structure. It contains a set of attributes that describe the thread and the thread context (Thread Context). The context is a memory block that contains a set of CPU registers.X86The thread context is about 700 bytes,X64AndIA64The context size is about 1240 bytes and 2500 bytes respectively.

2. Thread environment block (thread environment block, Teb)Teb is a memory block allocated and initialized in user mode (address space that can be quickly accessed by application code). Teb requires one memory page (4 kb in x86 and x64 CPUs,IA648 kb in CPU). Teb contains the thread's exception handling Link (Head), The thread enters eachTryAll blocks insert a node at the beginning of the chain and exit.TryIn addition, Teb also contains the "Thread Local Storage" data of the process and some data structures used by the GDI and OpenGL graphics.

3. User-mode Stack)The local variable used by the user mode stack to store the data transmitted to the method is a real parameter. It also contains an address, indicating where the thread should start executing when the method returns. By default,WindowsAllocate 1 MB of memory to the user mode stack of each thread.

4. Kernel Mode Stack)The application code often needs to call the kernel-mode functions of the operating system. For security reasons, the OS will change the called parameters fromUser Mode StackCopyKernel Mode StackAfter the copy is completeOSThese parameters are verified. in addition, the methods in kernel mode also need to be called to each other. They rely on this stack to save local variables, method parameters, and return addresses. on 32-bit systems, this stack accounts for 12 kb, and 64-bit systems account for 24 KB.

5. dll thread connection and thread separation notifications (DLL thread-Attach and thread-Detach notifications)When a new thread is created in the process, the dllmain method of all DLL loaded in the process will be called and a dll_thread_attach flag will be passed to the method. when a thread terminates, it also calls the dllmain method of all DLL loaded in the process and passes a dll_thread_detach mark to the method. however, for the DLL written in C # And other hosting languages, this notification will not be received because there is no dllmain method, which improves the performance. for unmanaged DLL, you can call Win32 disablethreadlibrarycils to decide to ignore these notifications.

Thread Switching

After the thread virtualizes the CPU, it becomes a logical CPU, while the physical CPU has only one (multi-core CPU has multiple CPUs). One CPU can only do one thing at a time. at any time, Windows only assigns one thread to one CPU, which allows a "time slice" to run. Once the time slice expires, Windows switches the context to another thread, perform the following operations for each context switch:

1. Save the value in the CPU register in a context structure of the currently running thread kernel object.

2. schedule the next thread to run. If this thread belongs to another process, WIndows also needs to switch the virtual address space first.

3. Load the value in the Context Structure of the selected thread to the CPU register.

Rational use of threads

Generally, you may use threads to isolate code from other code to improve program reliability, or use threads to simplify coding or use threads for concurrent execution. as we can see above, creating a thread requires a lot of resources. When creating a thread, you should let it do things, rather than idle.

Open the task manager and you can find that some programs have created many threads, but most of the CPU occupied by this application is 0, that is, it is not doing things! When writing an application, you can consider whether it is necessary to create this thread and whether it can be replaced by other economical methods.

In fact, I am not quite clear why Jeffrey Richter said on page 698th, "well, without a doubt, we can say
For sure that all of these applications we 've just discussed are using threads
Inefficiently. ", an application creates many threads, because they are not working now, so they are considered inefficient?
If the threads are for your high response when operating the application, I think these threads that are not currently in use have value. if you understand "inefficiency" from another perspective ",
I think it is not working most of the time. You delete them. If your application response becomes insensitive, what should you do?

Thread Scheduling and priority

The operating system needs to determine at what time the thread is scheduled and how long it takes to run. The context structure reflects the CPU register status of the thread during the last execution of the current thread. After a time slice, windows checks all the thread kernel objects. Among these objects, only those threads that are not waiting for are suitable for scheduling. You can use Spy ++ to view the number of times each thread is switched to the context.

The priority is represented by 0-31, and 0 indicates the lowest priority. The system first checks the thread whose priority is 31, and uses (Round-RobinAs long as there is a thread with a scheduling priority of 31, the system will never give the thread with a priority of 0 to 30 to the CPU for execution. This situation is calledHunger(Starvation). Actually, when writing a program, we don't know what priority should be specified for the thread I just created. Why is it 20 instead of 21? Therefore, Windows exposes an abstraction layer of the priority system, which is lowest, below normal, normal, above normal, and highest. In the code, you can set the priority attribute of the thread to specify the priority level of the thread.

Foreground thread and background thread

This concept is not hard to understand. for example, if an application creates a new thread, the thread can only be a foreground thread or a background thread. If a foreground thread is created, the execution of the program ends only when all foreground threads are completed. If the background thread is created and the foreground thread ends, no matter whether the background thread ends or not, the system will end the running of background threads and will not throw any exceptions.

You can set the isbackground attribute of the thread instance to determine whether the thread is a foreground thread or a background thread.

Link: http://www.cnblogs.com/technology/archive/2011/05/22/2053567.html

Reference: Jeffrey Richter <CLR via C #> Chapter 3, third edition

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.