Author: Lin Guanhong/The Ghost at my Fingertips
The Denver nuggets: juejin. Cn/user / 178526…
Blog: www.cnblogs.com/linguanh/
Making: github.com/af913337456…
Tencent cloud column: cloud.tencent.com/developer/u…
directory
- preface
- coroutines
- Characteristics of coroutines
1
和2
点- Points 3 and 4 in characteristics
- And threads as a whole
preface
Happy National Day everyone. It has been almost two months since my last post, and 19 years have come to an end. The current summary is more in the draft than issued, this time to share in detail in Go, thread and coroutine difference and relationship.
coroutines
Coroutine, English name Coroutine. But in Go, the English name for the coroutine is gorutine. It is often used for multitasking, or concurrent jobs. Yeah, the one for the multithreading homework.
Although we don’t have to write code like threads directly to do concurrency in Go, Go’s coroutines rely on threads to do so.
Let’s look at the differences.
The basic introduction of threads, here please do your own online search for articles, because there are many excellent introduction articles about threads.
Characteristics of coroutines
Here’s a straightforward list of thread characteristics, then parse them from the examples.
- Multiple coroutines can be managed by one or more threads,
Scheduling of coroutines
Occurs in its thread. - Can be scheduled. Scheduling policies are defined by application layer code and can be highly customized.
- High execution efficiency.
- Occupies less memory.
The above1
和 2
点
Let’s look at an example:
func TestGorutine(t *testing.T) {
runtime.GOMAXPROCS(1) // Specify a maximum P of 1, so that the maximum number of threads managed by coroutines is 1
wg := sync.WaitGroup{} // Control exits the program until all coroutines are executed
wg.Add(2)
// Run a coroutine
go func(a) {
fmt.Println(1)
fmt.Println(2)
fmt.Println(3)
wg.Done()
}()
// Run the second coroutine
go func(a) {
fmt.Println(65)
fmt.Println(66)
// Set a sleep so that the coroutine executes timeout and is suspended, causing timeout scheduling
time.Sleep(time.Second)
fmt.Println(67)
wg.Done()
}()
wg.Wait()
}
Copy the code
The code snippet above runs two coroutines, and after running, the order of the output is observed to be staggered. May be:
65, 66, 1, 2, 3, 67Copy the code
It means that while executing coroutine A, it can interrupt at any time to execute coroutine line B, and coroutine B can also interrupt during execution to execute coroutine A.
It looks like coroutine A and B are running as thread switches, but notice that both A and B are running on the same thread. Their scheduling is not thread switching, but pure application state coroutine scheduling.
Why specify the following two lines of code in the above code?
runtime.GOMAXPROCS(1)
time.Sleep(time.Second)
Copy the code
This requires you to take a look at the basics of Go’s coroutine scheduling, as shown in my previous scheduling analysis article:
Go coroutine scheduling mechanism
If runtime.gomaxprocs (1) is not set, then the program will start a corresponding number of P’s based on the number of CPU cores in the operating system, resulting in multiple M’s, or threads. Then the coroutines in our program will be allocated to different threads. For demonstration purposes, set the number to 1, so that they are all allocated to the same thread, stored in the thread’s coroutine queue, waiting to be executed or scheduled.
Points 3 and 4 in coroutine characteristics.
- High execution efficiency.
- Occupies less memory.
Because the scheduling switch of coroutine is not thread switch, but controlled by the program itself, therefore, there is no overhead of thread switch, compared with multithreading, the more threads, the more obvious performance advantage of coroutine. Scheduling occurs in application state rather than kernel state.
The cost of memory, using the memory of the thread it is in, means that the memory of a thread can be used by multiple coroutines.
Secondly, the scheduling of coroutines does not need the locking mechanism of multithreading, because there is only one thread, and there is no simultaneous writing variable conflict, so the execution efficiency is much higher than multithreading.
And threads as a whole
Comparison of some | thread | coroutines |
---|---|---|
Data is stored | Kernel state memory space | Usually user-mode memory space provided by threads |
Switching operation | The operation is ultimately done at the kernel layer, where the application layer calls the syscall low-level functions provided by the kernel layer | The application layer uses code for simple on-site save and restore |
Task scheduling | Implemented by the kernel, preemption mode, depends on various locks | By the user – mode implementation of the specific scheduler. An example is the go coroutine scheduler |
Voice support | Most programming languages | Some languages: Lua, Go, Python… |
Implementation specification | According to modern operating system specifications | There is no uniform specification. Implemented by the developer at the application level, highly customizable, such as single-threaded threads. Different scheduling strategies, and so on |
Personal ads
My technical book “Blockchain Ethereum DApp Development Combat” has been published and can be purchased online, suitable for elementary and intermediate blockchain technology related research and development personnel to read.