Multithreading foundation of multithreading series (1)


Thread related concepts

Before learning about multithreading, let’s take a look at a few concepts related to multithreading.

process: process is the concept of computer. The program occupies the total of all computing resources when the server is running. An application program is a process when it runs. Open the task manager of windows, as shown in the figure below

thread Thread is also the concept of computer. Thread is the smallest unit of a process and the smallest unit of a program when responding to the operating system. A process consists of at least one thread (main thread). Threads and processes also occupy a certain amount of CPUMemory, network, hard disk IO, etc. A thread belongs to a process. When the process is destroyed, the thread is destroyed.

handleLong is a type of digital, which is used by the operating system to identify the application, and has the meaning of a primary key or ID number.

Multithreading: a process or an application has multiple threads running to participate in the calculation.

Multithreading in C ා

Thread class is the encapsulation of thread object by C ා. It began to appear in. Net framework 1.0. In the following multithreading series of articles, we will talk about the use of multithreading API in different versions of. Net framework. In this article, let’s have a preliminary understanding of multithreading.

Why can multithreading be used

1: Multi core technology and analog core technology of CPU:

For example, the parameter concept of computer is 4 cores and 8 threads, so-called 4 cores and 8 threads, 4 cores refer to the physical core. The total number of virtual threads is 8 for each physical thread, which is simulated by two physical threads. The hyper threading technology of four cores and eight threads means that when each CPU core is not fully loaded, its remaining consumption can be simulated as a virtual core. A single physical core can only process one thread at the same time point. By using hyper threading technology, a single physical core can realize thread level parallel computing.

2: CPU slicingIn fact, the CPU can only process one task at a time, but because of its powerful computing power, it can respond to different tasks in one second. The processing power of one second is divided into 10 parts: 1 to 100 ms processing task a, 101 to 200 ms processing task B, 201 to 300 ms processing task C From a macro point of view, it feels that multiple tasks are executing concurrently, which is the CPU fragmentation.

Learn about synchronization and asynchrony

Synchronization method: initiate the call and continue to the next line after the call is completed. It is very consistent with the development thinking and is executed from top to bottom in an orderly manner;

Asynchronous method: initiate the call, do not wait for completion, go directly to the next line, and enable a new thread to complete the calculation.

Synchronous method is like a sincere invitation to dinner. The guest says that he has something to do and needs to be busy for a while. The person who invites the meal will wait for the guest to have a meal after he is busy. Asynchronous method is like politely inviting someone to dinner. The guest says that he has something to do, and the person who invites the meal says that you should be busy first, and then go to eat by yourself.

Comparison between synchronous and asynchronous

The interface of synchronous method card, the main thread (UI) thread is busy with calculation, there is no time for other attention, the asynchronous method does not card interface: the main thread is idle, and the calculation task is handed over to the sub thread to complete, so as to improve the user experience. If you click the button in WinForm to call a complex task calculation in a synchronous way, the interface will be temporarily stuck until the task calculation is finished.

In the web application, sending a short message notice and recording a log can be executed in an asynchronous manner. The client does not need to wait for the SMS to be sent or the log is recorded successfully to receive the response from the server.

In order to clearly explain the situation, the test program comparison method is adopted here. The test program interface is as follows:


Calculation task:

private void DoSomeThing(string btnName) {
            Console.WriteLine ($"{btnname} starts, current thread ID:{ Thread.CurrentThread.ManagedThreadId }");
            long lResult = 0;
            for (long i = 0; i < 1_000_000_000; i++)
                lResult += i;
            Console.WriteLine ($"{btnname} ends, current thread ID:{ Thread.CurrentThread.ManagedThreadId }");

Synchronous mode call:

private void BtnSync_Click(object sender, EventArgs e)
            Console.WriteLine($"btnSync_Click Start {Thread.CurrentThread.ManagedThreadId.ToString("00")}" +
                $" {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
            Stopwatch stopwatch = new Stopwatch();
            for (int i = 0; i < 5; i++)
                string name = string.Format($"btnSync_Click_{i}");
            Console.WriteLine ($"synchronization method time consumption:{ stopwatch.ElapsedMilliseconds }");
            Console.WriteLine($"DoSomeThing End {Thread.CurrentThread.ManagedThreadId.ToString("00")} " +
                $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");

Synchronous mode call execution result:


CPU usage during synchronous mode call:

Call in asynchronous mode:

private void BtnAsync_Click(object sender, EventArgs e)
            Console.WriteLine($"btnAsync_Click Start {Thread.CurrentThread.ManagedThreadId.ToString("00")}" +
                $" {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
            Stopwatch stopwatch = new Stopwatch();
            List tasks = new List();
            for (int i = 0; i < 5; i++)
                int k = i;
                tasks.Add(Task.Run(()=> {
                    string name = string.Format($"btnAsync_Click{k}");
            Task.Run(()=> {
                Console.WriteLine ($"asynchronous method time consuming:{ stopwatch.ElapsedMilliseconds }");
                Console.WriteLine($"DoSomeThing   End {Thread.CurrentThread.ManagedThreadId.ToString("00")}" +
                    $" {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");

Asynchronous call execution result:

CPU usage when calling in asynchronous mode:


The synchronization method is slow, and the above figure takes 16402 MS because there is only one thread to calculate. The asynchronous method is fast, and the above diagram takes 10524 MS, because there are multiple threads involved in the calculation. By observing the usage of synchronous and asynchronous calls, the line graph analysis shows that multithreading is actually the exchange of resources for performance. Is the more threads open in an application, the better? No, because opening more resources requires more computer resources. Resources are limited, and resource scheduling also needs to consume resources. Just as project managers manage developers to ensure project progress, project managers also need wages to schedule (manage) developers.

An order table statistics is time-consuming. Can multithreading be used to optimize performance? No! This operation contains only one task and can’t be calculated in parallel, just like a teacher can’t teach in two classes at the same time. If an operation needs to call the interface, read and write hard disk files, and do data calculation while querying the database, multi threading can be used to optimize the performance, because multiple tasks can be calculated in parallel.

The synchronous method is orderly, and asynchronous multithreading is out of order

Start disorderly: thread resources belong to unmanaged resources, which are applied to the operating system by the program, and are determined by the scheduling policy of the operating system. Therefore, the startup sequence is random. The CPU uses the same thread to calculate the same task, and the execution time is uncertain. So, the end is also out of order. Be careful when using multithreading, especially when there is a sequence requirement between multithreads, by delaying a little time( Thread.Sleep () to control the execution order, which is not reliable. In the next part, we will continue to study the thread class of multithreading multithreading series (2) in C ා