官术网_书友最值得收藏!

Goroutines

It's now time to dig deeper into the clean API that Go provides in order to write concurrent software with ease.

A goroutine is simply defined as a light-weight thread that you can use in your program; it's not a real thread. In Go, when you define a piece of code as a new goroutine, you basically tell the Go runtime that you would like this piece of code to run concurrently with other goroutines.

Every function in Go lives in some goroutine. For example, the main function that we discussed in the previous chapter, which is usually the entry point function for your program, runs on what is known as the main goroutine.

So, how do you create a new goroutine? You just append the go keyword before the function that you would like to run concurrently. The syntax is quite simple:

go somefunction()

Here, somefunction() is the piece of code that you would like to run concurrently. Whenever you create a new goroutine, it will get scheduled to run concurrently, and will not block your current goroutine.

Here is a trivial, but more complete piece of code to help us understand the concept of goroutines:

package main

import (
"fmt"
"time"
)

func runSomeLoop(n int) {
for i := 0; i < n; i++ {
fmt.Println("Printing:", i)
}
}
func main() {
go runSomeLoop(10)
//block the main goroutine for 2 seconds
time.Sleep(2 * time.Second)
fmt.Println("Hello, playground")
}

The preceding code is a simple program that runs a function called runSomeLoop() on a new goroutine. This means that runSomeLoop() will run concurrently to the main() function. In the program, we made use of a function called Sleep(), which exists in the time package. This function will block the main goroutine in order to give runSomeLoop() a chance to run and finish. If we don't block the main goroutine in this example, the main goroutine will likely finish, and then exit the program before runSomeLoop() gets a chance to fully run. There are cases when This is a byproduct of the fact that goroutines are concurrent, which is why invoking a new goroutine does not block your current goroutine. 

Here's how the output of the program will look:

Printing: 0 
Printing: 1
Printing: 2
Printing: 3
Printing: 4
Printing: 5
Printing: 6
Printing: 7
Printing: 8
Printing: 9
Hello, playground

This shows us that the runSomeLoop() goroutine managed to run at the same time when the main goroutine was sleeping. When the main goroutine woke up, it printed Hello, playground before it exited.

So, what if we removed the time.Sleep() function that blocked the main goroutine? Take a look at the following code block:

package main

import (
"fmt"
)

func runSomeLoop(n int) {
for i := 0; i < n; i++ {
fmt.Println("Printing:", i)
}
}
func main() {
go runSomeLoop(10)
fmt.Println("Hello, playground")
}

You will get the following result:

Hello, playground

You can see that runSomeLoop() didn't get the chance to run before the main goroutine exited.

Goroutines are very light from a memory and resources point of view; a production Go program will typically run hundreds and thousands of goroutines. The ability to produce goroutines with such simple API is arguably one of the most powerful features of the Go language, according to many of Go's users.

Let's take a look at Go channels in the next section.

主站蜘蛛池模板: 盐源县| 吴桥县| 波密县| 余江县| 衡水市| 三亚市| 铜梁县| 崇义县| 马尔康县| 鞍山市| 锡林浩特市| 英吉沙县| 泸定县| 瑞安市| 灵寿县| 南召县| 贡嘎县| 东明县| 米易县| 抚宁县| 睢宁县| 贵港市| 黄大仙区| 丹阳市| 乐平市| 屯昌县| 嵩明县| 安新县| 定兴县| 永吉县| 丹阳市| 皋兰县| 马尔康县| 儋州市| 恩施市| 上饶县| 察哈| 定陶县| 金寨县| 松江区| 泽州县|