This article will continue to focus on the basics of the Go language. We'll talk a little bit about performance and extend our application by creating some simple goroutines.
We will also pay attention to some of the underlying execution logic of the Go language and the differences between the Go language and other languages.
Before continuing the discussion, we must understand the concepts of concurrency and parallelism. Golang can achieve concurrency and parallelism.
Let’s take a look at the difference between concurrency and parallelism.
An application may handle multiple processes to accomplish its intended functionality. Let's assume a simple e-commerce website. It has been evaluated that the following tasks need to be executed concurrently:
Display the latest transaction and product information at the top of the web page;
Displays the current number of online users on the website;
Updates the shopping cart details when the user selects the product ;
Countdown to "Target Transaction Volume";
The website needs to run all these tasks at the same time , to keep users relevant to the website and to make the website attractive to users and attract more business.
Therefore, in order to meet business needs, a simple application or website may contain a set of tasks running in the background.
In the two examples shown above, multiple tasks are executed simultaneously, but there are still differences between them. Let's study further to understand better.
Assume a scenario where we have a single-core machine that needs to complete multiple tasks, but there is a limit. At any time, on the single-core machine Only one task can be run.
In the concurrency model, there is context switching between tasks. The program is processing multiple tasks, but since we only have a single core, the tasks cannot be executed together.
The context switching between tasks is so fast that we feel that the tasks are running simultaneously.
There is no factor for parallel execution during the execution process, because it is a single-core system and multiple processes cannot be executed in parallel.
As shown in the figure above, Concurrency (Without Parallelism) has two tasks that need to be executed concurrently. At any time, only one task is running and there are context switches between tasks.
When using a single core, there is a limit on the number of cores. If we increase the number of cores in the machine, we can execute tasks on different cores simultaneously.
In the above figure (Parallelism), there are two tasks executing at any time, and these two tasks run on different cores.
Concurrency is the simultaneous processing of multiple tasks within a certain period of time, and parallelism is the ability to execute multiple tasks at a certain point in time.
Using the Go language, you can easily scale your program from concurrent to parallel execution.
To use Go language to achieve concurrency and parallelism, we need to understand the concept of Goroutines. The coroutine of the Go language can be understood as a wrapper on a thread, managed by the Go runtime rather than the operating system.
The Go runtime is responsible for allocating and recycling resources to coroutines. Coroutines are very similar to threads that complete multitasking but consume fewer resources than operating system threads. There is not a one-to-one relationship between coroutines and threads.
We can "disassemble" the application into multiple concurrent tasks, which can be completed by different goroutines. In this way, Go language concurrency can be achieved .
Advantages of coroutines:
More lightweight;
Easy Extension;
Virtual thread;
Requires less initial memory (2KB);
If necessary, the Go runtime can allocate more memory;
Let’s look at a simple example:
package main import ( "fmt" "time" ) func main() { start := time.Now() func() { for i:=0; i < 3; i++ { fmt.Println(i) } }() func() { for i:=0; i < 3; i++ { fmt.Println(i) } }() elapsedTime := time.Since(start) fmt.Println("Total Time For Execution: " + elapsedTime.String()) time.Sleep(time.Second) }
The above code executes two independent functions in the main function in sequence.
The code does not use coroutines, and the program is executed in the same thread. The program does not have any concurrency, and the execution results are as follows:
#The code is executed in order, starting from the main function, executing the first function first, and then executing the second function. Finally exit normally from the main function.
No coroutines are used in the above scenario examples. We can use the go keyword to start the coroutine before executing the function.
Still the above example, let’s take a look at what it will look like after using the go keyword to open the coroutine:
package main import ( "fmt" "time" ) func main() { start := time.Now() go func() { for i:=0; i < 3; i++ { fmt.Println(i) } }() go func() { for i:=0; i < 3; i++ { fmt.Println(i) } }() elapsedTime := time.Since(start) fmt.Println("Total Time For Execution: " + elapsedTime.String()) time.Sleep(time.Second) }
Execute the above code output:
The above code uses the go keyword to open two coroutines and execute their respective functions, including the main coroutine. There are a total of 3 coroutines.
In the above code, we use the go keyword to start the coroutine, and the function will be executed in the coroutine, not in the main Executed in coroutines, this increases concurrency and improves program performance.
In Go language, you can set the number of cores for the program to run through the following simple line of code (PS : Starting from Go 1.5, the default value of Go's GOMAXPROCS has been set to the number of cores of the CPU).
runtime.GOMAXPROCS(4)
This can specify that the program runs on a multi-core machine. The above line of code specifies that the program can use four cores to execute.
Once a coroutine is created, it can be executed in different cores, thereby achieving parallelism and speeding up program execution.
package main import ( "fmt" "time" "runtime" ) func main() { runtime.GOMAXPROCS(4) start := time.Now() go func() { for i:=0; i < 3; i++ { fmt.Println(i) } }() go func() { for i:=0; i < 3; i++ { fmt.Println(i) } }() elapsedTime := time.Since(start) fmt.Println("Total Time For Execution: " + elapsedTime.String()) time.Sleep(time.Second) }
The above code output is as follows:
Concurrency and parallelism can be easily achieved using the Go language. Simply add the go keyword before the function to increase program execution speed.
The above is the detailed content of Go Basics Goroutine. For more information, please follow other related articles on the PHP Chinese website!