Home > Article > Backend Development > What is goroutine in Go language?
Goroutine is a lightweight thread implementation in the Go language. It is a lightweight abstraction built on threads and is managed by the Go runtime. Goroutine allows us to execute multiple functions or methods in parallel in the same address space at a very low cost; compared to threads, its creation and destruction are much less expensive, and its scheduling is independent of threads.
The operating environment of this tutorial: Windows 7 system, GO version 1.18, Dell G3 computer.
When writing a Socket network program, you need to prepare a thread pool in advance to allocate a thread for each Socket sending and receiving packets. Developers need to establish a corresponding relationship between the number of threads and the number of CPUs to ensure that each task can be allocated to the CPU for processing in a timely manner, while avoiding the loss of efficiency caused by frequent switching of multiple tasks between threads.
Although, the thread pool provides an abstract mechanism for thread allocation for logic writers. However, when faced with concurrency and thread processing requirements that may occur anytime and anywhere, the thread pool is not very intuitive and convenient. Is there a mechanism: if the user allocates enough tasks, the system can automatically help the user allocate the tasks to the CPU so that these tasks can run as concurrently as possible. This mechanism is called goroutine in Go language.
Goroutine is a lightweight thread implementation in the Go language and is managed by the Go runtime. Go programs will intelligently allocate tasks in goroutines to each CPU.
Goroutine is a lightweight abstraction built on threads. It allows us to execute multiple functions or methods in parallel in the same address space at a very low cost. Compared with threads, its creation and destruction are much less expensive, and its scheduling is independent of threads.
The Go program starts from the main() function of the main package. When the program starts, the Go program will create a default goroutine for the main() function.
Use ordinary functions to create goroutine
Use the go keyword in the Go program to create a goroutine for a function. A function can be created with multiple goroutines, and one goroutine must correspond to one function.
1) Format
Creating a goroutine for a common function is written as follows:
go 函数名( 参数列表 )
Function name: to be called Function name.
Parameter list: Parameters that need to be passed in when calling the function.
When using the go keyword to create a goroutine, the return value of the called function will be ignored.
If you need to return data in goroutine, please use the channel feature introduced later to pass the data out from goroutine as a return value through the channel.
2) Example
Use the go keyword to execute the running() function concurrently and print the counter every second, while the main goroutine waits for user input , two actions can be performed simultaneously. Please refer to the following code:
package main import ( "fmt" "time" ) func running() { var times int // 构建一个无限循环 for { times++ fmt.Println("tick", times) // 延时1秒 time.Sleep(time.Second) } } func main() { // 并发执行程序 go running() // 接受命令行输入, 不做任何事情 var input string fmt.Scanln(&input) }
The command line output is as follows:
After the code is executed, the command line will continuously output ticks, and you can use fmt.Scanln () accepts user input. Both steps can be carried out simultaneously.
The code description is as follows:
In line 12, use for to form an infinite loop.
In line 13, the times variable continues to increase in the loop.
Line 14, output the value of the times variable.
Line 17, use time.Sleep to pause for 1 second and then continue the loop.
On line 25, use the go keyword to let the running() function run concurrently.
Line 29, accept user input until the Enter key is pressed, the input content is written into the input variable and returned, and the entire program terminates.
The execution sequence of this code is as shown in the figure below.
Figure: Concurrent running diagram
In this example, when the Go program is started, the runtime (runtime) will create a goroutine for the main() function by default. When the go running statement is executed in the goroutine of the main() function, the goroutine belonging to the running() function is created, and the running() function starts executing in its own goroutine. At this point, main() continues to execute, and the two goroutines operate simultaneously through the scheduling mechanism of the Go program.
Creating a goroutine using an anonymous function
You can also start a goroutine for an anonymous function or closure after the go keyword.
1) The format of using anonymous functions to create goroutine
When using anonymous functions or closures to create goroutines, in addition to writing the function definition part after go, You also need to add the calling parameters of the anonymous function, in the following format:
go func( 参数列表 ){ 函数体 }( 调用参数列表 )
Among them:
Parameter list: The list of parameter variables in the function body.
Function body: the code of the anonymous function.
调用参数列表:启动 goroutine 时,需要向匿名函数传递的调用参数。
2) 使用匿名函数创建goroutine的例子
在 main() 函数中创建一个匿名函数并为匿名函数启动 goroutine。匿名函数没有参数。代码将并行执行定时打印计数的效果。参见下面的代码:
package main import ( "fmt" "time" ) func main() { go func() { var times int for { times++ fmt.Println("tick", times) time.Sleep(time.Second) } }() var input string fmt.Scanln(&input) }
代码说明如下:
第 10 行,go 后面接匿名函数启动 goroutine。
第 12~19 行的逻辑与前面程序的 running() 函数一致。
第 21 行的括号的功能是调用匿名函数的参数列表。由于第 10 行的匿名函数没有参数,因此第 21 行的参数列表也是空的。
扩展知识:Goroutine与线程的区别
许多人认为goroutine比线程运行得更快,这是一个误解。Goroutine并不会更快,它只是增加了更多的并发性。当一个goroutine被阻塞(比如等待IO),golang的scheduler会调度其他可以执行的goroutine运行。与线程相比,它有以下的几个优点:
内存消耗更少:
Goroutine所需要的内存通常只有2kb,而线程则需要1Mb(500倍)
创建与销毁的开销更小:
由于线程创建时需要向操作系统申请资源,并且在销毁时将资源归还,因此它的创建和销毁的开销比较大。相比之下,goroutine的创建和销毁是由go语言在运行时自己管理的,因此开销更低。
切换开销更小:
只是goroutine之于线程的主要区别,也是golang能够实现高并发的主要原因。线程的调度方式是抢占式的,如果一个线程的执行时间超过了分配给它的时间片,就会被其他可执行的线程抢占。在线程切换的过程中需要保存/恢复所有的寄存器信息,比如16个通用寄存器,PC(Program Counter)、SP(Stack Pointer)段寄存器等等。而goroutine的调度是协同式的,它不会直接地与操作系统内核打交道。当goroutine进行切换的时候,之后很少量的寄存器需要保存和恢复(PC和SP)。因此goroutine的切换效率更高。
The above is the detailed content of What is goroutine in Go language?. For more information, please follow other related articles on the PHP Chinese website!