. NET multi-thread programming (1): multi-task and multi-thread

Source: Internet
Author: User

In the. NET multi-threaded programming series, we will discuss all aspects of multi-threaded programming. First, I will introduce the concept of multithreading and the basic knowledge of multithreading programming at the beginning of this article. In the next article, I will explain it one by one. . NET platform multi-threaded programming knowledge, such as the important classes and methods of the System. Threading namespace, and some example programs to illustrate.

Introduction

The early computing hardware was very complex, but the functions executed by the operating system were indeed very simple. At that time, the operating system can only execute one task at any time point, that is, only one program can be executed at the same time. The execution of multiple tasks must take turns and wait in queue in the system. Due to the development of computers, the system requires more and more powerful functions. At this time, the concept of time-sharing operations emerged: each running program occupies a certain processor time, the next program waiting for the queue to wait for the processor resources starts to run. Note that the program is not running after a certain processor time, and the processor time may need to be allocated again or multiple times. We can see from this that this execution method is obviously parallel execution of multiple programs, but at the macro level, we feel that multiple tasks are executed at the same time, therefore, the concept of multi-task was born. Each running program has its own memory space, its own stack and environment variable settings. Each program corresponds to a process and represents executing a large task. A process can start another process, which is called a sub-process. The execution of a parent process and a child process has only a logical relationship, and there is no other relationship, that is, their execution is independent. However, a large program (representing a large task) can be divided into many small tasks. For functional purposes or to speed up the operation, you may need to execute multiple tasks at the same time (each task is assigned a multi-thread to execute the corresponding tasks ). For example, you are viewing some wonderful articles through your web browser. You need to download some good articles. You may need to add some wonderful articles to your favorites, you can use your printer to print these online articles. Here, the browser downloads an article in HTML format and prints the article. This means that a program executes multiple tasks at the same time, and each task is assigned a thread to complete. Therefore, we can see that a program can execute multiple tasks simultaneously through multiple threads.

Multithreading VS multitasking

As mentioned above, multitasking refers to the ability to execute multiple programs at the same time, relative to the operating system, but in fact, it is impossible to execute more than two programs at the same time with only one CPU. High-speed switching between programs allows all programs to get a shorter CPU time in a short period of time. From the user's perspective, it seems that multiple programs are being executed at the same time. Multithreading refers to the ability to execute different parts of the same program at the same time, and each part of execution becomes a thread. Therefore, when writing applications, we must be well designed to avoid interference between different threads during execution. This helps us design robust programs so that we can add threads whenever needed.

Thread Concept

A thread can be described as a microprocess, which has the starting point, execution sequence, and end point. It maintains its own stacks, which are used for exception handling, priority scheduling, and other information required when the system resumes thread execution. From this concept, it seems that there is no difference between a thread and a process. In fact, there must be a difference between a thread and a process:

A complete process has its own independent memory space and data, but threads in the same process share the memory space and data. A process corresponds to a program, which is composed of threads that run independently and simultaneously in the same program. A thread is also called a lightweight process that runs in parallel in a program. A thread is called a lightweight process because it runs dependent on the context environment provided by the process and uses process resources.

In a process, thread scheduling can be preemptible or non-preemptible.

In preemption mode, the operating system allocates CPU time to each process. Once the current process is used up, the operating system determines which thread occupies the CPU time. Therefore, the operating system regularly interrupts the threads currently being executed and allocates the CPU to the next thread waiting for the queue. Therefore, no thread can exclusively occupy the CPU. The CPU usage time of each thread depends on the process and operating system. The process is allocated to every thread for a short time, so that we feel that all threads are executed at the same time. In fact, the system runs each process for 2 milliseconds and then Schedules other threads. It also maintains all threads and loops and allocates a small amount of CPU time to threads. The thread switching and scheduling are so fast that it feels that all threads are executed synchronously.

What does scheduling mean? Scheduling means that the processor stores the status of the process whose CPU time is to be executed and the status of the process loaded at a certain time in the future to resume its operation. However, this method also has some shortcomings. A thread can interrupt the execution of another thread at any given time. Assume that a thread is writing data to a file, and the other thread interrupts its operation and writes data to the same file. Windows 95/NT, UNIX uses this thread scheduling method.

In non-preemptible scheduling mode, each thread takes up the CPU time as much as the CPU time required. In this scheduling mode, a thread with a long execution time may cause all other threads that require CPU to starve to death ". When the processor is idle, that is, when the process does not use the CPU, the system can allow other processes to temporarily use the CPU. The CPU-consuming thread has control over the CPU. Other threads can use the CPU only when it actively releases the CPU. Some I/O and Windows 3. X uses this scheduling policy.

In some operating systems, both scheduling policies are used. Non-preemptible scheduling policies are generally used when the thread running priority is normal, while high-priority thread scheduling uses preemptible scheduling policies. If you are not sure that the system uses the scheduling policy, it is safer to assume that the preemptible scheduling policy is unavailable. When designing an application, we think that the threads that occupy more CPU time will release the control of CPU at a certain interval, at this time, the system will check the threads in the waiting queue with the same priority or higher priority as the currently running threads, so that these threads can use the CPU. If the system finds such a thread, it immediately suspends the current thread and activates the thread that meets the conditions. If no thread with the same priority or higher level is found, the current thread continues to occupy the CPU. When the executing thread wants to release control of CPU to a low-priority thread, the current thread will be transferred to sleep state, so that the low-priority thread will occupy the CPU.

In a multi-processor system, the operating system will allocate these independent threads to different processors for execution, which will greatly speed up program running. The thread execution efficiency will be greatly improved, because the time-sharing single processor of the thread is converted into distributed multi-processor execution. This type of multi-processor is very useful in 3D modeling and graphic processing.

Need multithreading?

We issued a print command to ask the printer to print the task. Suppose the computer stops responding at this time and the printer is still working, isn't it because we are waiting for the printer to print at a slow speed? Fortunately, this does not happen. We can also listen to music or draw pictures while working on the printer. Because we use independent multithreading to execute these tasks. You may be surprised when multiple users access the database or web server at the same time. How do they work? This is because an independent thread is set up for each user connected to the database or web server to maintain the user's status. If a program runs in a certain order, this method may cause problems or even cause the entire program to crash. If the program can be divided into different independent tasks and multithreading is used, even if a part of the task fails, it will not affect other tasks and will not cause the whole program to crash.

There is no doubt that writing a multi-threaded program gives you a powerful tool to drive a non-multi-threaded program, but multithreading may also become a burden or a huge cost. Improper use may cause more disadvantages. If a program has many threads, the threads of other programs must only occupy less CPU time, and a large amount of CPU time is used for thread scheduling; the operating system also needs enough memory space to maintain the context information of each thread. Therefore, a large number of threads will reduce the operating efficiency of the system. Therefore, if multithreading is used, the program multithreading must be well designed; otherwise, the benefits will be far less than the disadvantages. Therefore, we must be careful when using multithreading to create, schedule, and release these threads.

Multithreading Program Design tips

There are multiple ways to design multi-threaded applications. As shown in the following article, I will provide detailed programming examples through which you can better understand multithreading. Threads can have different priorities. For example, in our applications, drawing graphics or performing a large number of operations must also accept user input, obviously, the user's input needs to be responded immediately, while the drawing or operation takes a lot of time. The pause is not a problem, so the user's input thread will need a high level of leisure, graphics Rendering or low-priority operations. These threads are independent of each other and do not affect each other.

In the above example, drawing a graph or a large number of operations obviously requires a lot of CPU time. During this time, you do not have to wait for them to complete execution before entering information, therefore, we design the program into two independent threads, one responsible for user input and the other responsible for processing those time-consuming tasks. This will make the program more flexible and responsive. At the same time, the user may cancel the task at any time during running. In this example, the program should always be responsible for receiving messages from the system. If the program is busy with a task, the screen may become blank, which obviously requires our program to handle such events. So I have to have a thread responsible for processing these messages, as I mentioned earlier, it should trigger the re-painting of the screen.

We should grasp a principle that we should give higher priority to tasks that require time to be obtained immediately, while other threads should have lower priority than her. The thread that listens to client requests should always have a high priority. For a task on the user interface that interacts with the user, it needs to get the first response because of this high priority.

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.