SoFunction
Updated on 2025-03-03

Use of Golang Goroutine

What is Goroutine

goroutine is the core of Go parallel design. Goroutine is actually a coroutine after all, it is smaller than threads. More than a dozen goroutines may be reflected in the underlying layer, which is five or six threads. The Go language helps you realize the memory sharing between these goroutines.

Execution of goroutine requires only a very small stack memory (about 4~5KB), and of course it will be scalable according to the corresponding data. Because of this, thousands of concurrent tasks can be run simultaneously. goroutine is easier to use, more efficient and lighter than thread.

Generally speaking, it is a bit too much for an ordinary computer to run dozens of threads, but the same machine can easily allow hundreds of goroutines to compete for resource.

The creation of Goroutine

Simply add the go keyword before the function call statement to create a concurrent execution unit.

The developer does not need to know any execution details, and the scheduler will automatically schedule it to the appropriate system thread for execution.

In concurrent programming, we usually want to split a process into pieces, and then let each goroutine be responsible for one piece of work. When a program starts, the main function runs in a separate goroutine, which we call main goroutine. A new goroutine will be created with a go statement. The concurrent design of the go language allows us to achieve this goal easily.

For example:

package main

import (
 "fmt"
 "time"
)

func foo() {
 i := 0
 for true {
 i++
 ("new goroutine: i = ", i)
 ()
 }
}

func main() {
 // Create a goroutine and start another task go foo()

 i := 0
 for true {
 i++
 ("main goroutine: i = ", i)
 ()
 }
}

result:

main goroutine: i =  1
new goroutine: i =  1
new goroutine: i =  2
main goroutine: i =  2
main goroutine: i =  3
new goroutine: i =  3
...

Goroutine Features

After the main go process exits, other children go processes will also automatically exit:

package main

import (
 "fmt"
 "time"
)

func foo() {
 i := 0
 for true {
 i++
 ("new goroutine: i = ", i)
 ()
 }
}

func main() {
 // Create a goroutine and start another task go foo()

 ( * 3)

 ("main goroutine exit")
}

Running results:

new goroutine: i =  1
new goroutine: i =  2
new goroutine: i =  3
main goroutine exit

runtime package

Gosched

() is used to transfer the CPU time slice occupied by the current goroutine, give up the execution permission of the current goroutine, and the scheduler arranges other waiting tasks to run, and resumes execution from the location where the CPU time slice is obtained next time.

It's a bit like running a relay race. A ran for a while and ran into the code () and handed the baton to B. A rested and B continued to run.

For example:

package main

import (
 "fmt"
 "runtime"
 "time"
)

func main() {
 // Create a goroutine go func(s string) {
 for i := 0; i < 2; i++ {
  (s)
 }
 }("world")

 for i := 0; i < 2; i++ {
 ()
 ("hello")
 }
 ( * 3)
}

Running results:

world
world
hello
hello

If there is no () then the run result is as follows:

hello
hello
world
world

Note: () Just give up a chance, look at the following code, and pay attention to the running results:

package main

import (
 "fmt"
 "runtime"
 "time"
)

func main() {
 // Create a goroutine go func(s string) {
 for i := 0; i < 2; i++ {
  (s)
  ()
 }
 }("world")

 for i := 0; i < 2; i++ {
 ()
 ("hello")
 }
}

Running results:

world
hello
hello

Why is world only once? Because we have said before that after the main goroutine exits, other job goroutines will also automatically exit.

Goexit

Calling () will immediately terminate the current goroutine execution, and the scheduler ensures that all registered defer delay calls are executed.

Note the difference from return, return returns returns the current function call to the caller.

For example:

package main

import (
 "fmt"
 "runtime"
 "time"
)

func main() {
 go func() {
 defer ("")
 func() {
  defer ("")
  () // Terminate the current goroutine  ("B") // Will not execute }()
 ("A") // Will not execute }() // Don't forget ()
 ( * 3)
}

Running results:



GOMAXPROCS

Call () to set the maximum value of the number of CPU cores that can be calculated in parallel, and return the value set by the last time (if not, it is the computer default).

package main

import (
 "fmt"
 "runtime"
)

func main() {
 (1) // Set cpu to single core
 for true {
 go (0) // Sub-go process (1) // Main go process }
}

Running results:

111111 ... 1000000 ... 0111 ...

When executing (1), at most one goroutine can be executed at the same time. So it will print a lot of 1. After a while, the GO scheduler will set it to sleep and wake up another goroutine. At this time, many 0s will be printed. When printing, goroutine is scheduled to the operating system thread.

package main

import (
 "fmt"
 "runtime"
)

func main() {
 (2)

 for true {
 go (0)
 (1)
 }
}

Running results:

111111111111111000000000000000111111111111111110000000000000000011111111100000...

Execution(2) When we use two CPUs, so the two goroutines can be executed together, alternately printing 0 and 1 at the same frequency.

Other functions in the runtime package

The Chinese document is here:/pkgdoc

Here are some functions and functions.

func GOROOT() string

GOROOT Returns the root directory of Go. If a GOROOT environment variable exists, the value of that variable is returned; otherwise, the root directory when Go was created.

func Version() string

Returns the version string of Go. It is either the hash submitted and the date of creation; or the hash issuing tags such as "go1.3".

func NumCPU() int

NumCPU returns the number of logical CPUs of the local machine (true · octa-core).

func GC()

GC performs a garbage collection. (If you are eager to do a garbage collection, you can call this function)

This is the end of this article about the use of Golang Goroutine. For more information about Golang Goroutine, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!