I studied goroutine today, so I will output it here!
Goroutine is executed in parallel by specifying a function with a go statement!
First, let's write an ordinary function.
package main
import (
"fmt"
"time"
)
func goroutine(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func hoge(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
goroutine("world")
hoge("hello")
}
Execution result
world
world
world
world
world
hello
hello
hello
hello
hello
This is just that the function is normally executed every 0.1 seconds from the top.
To do this in parallel, you can just prefix the function name with go. ** **
(Omitted because it is the same)
func main() {
go goroutine("world")
hoge("hello")
}
Execution result
hello
world
world
hello
world
hello
hello
world
world
hello
Since it is executed in parallel, the output will be mixed. Concurrent execution can be easily achieved simply by specifying the go statement in this way.
What happens if you comment out the time part here?
package main
import (
"fmt"
)
func goroutine(s string) {
for i := 0; i < 5; i++ {
//time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func hoge(s string) {
for i := 0; i < 5; i++ {
//time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go goroutine("world")
hoge("hello")
}
Execution result
hello
hello
hello
hello
hello
When I commented out the time part, only hello was output. This is because even if the goroutine thread is created by parallel processing, the processing of the main function has finished first. This is because the goroutine function ended without being executed.
Keep in mind that the program code will end ** even if the gorutine process is not completed.
So what can we do to avoid this?
Use ** sync.WaitGroup **.
sync.WaitGroup
package main
import (
"fmt"
"sync"
)
func goroutine(s string, wg *sync.WaitGroup) {
for i := 0; i < 5; i++ {
fmt.Println(s)
}
wg.Done()
}
func hoge(s string) {
for i := 0; i < 5; i++ {
fmt.Println(s)
}
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
go goroutine("world", &wg)
hoge("hello")
wg.Wait()
}
Declare a variable called wg
like this and describe that there is one parallel processing with
wg.Add (1)
.
I will pass the address of wg
to the goroutine function as an argument.
Then, by writing `wg.Wait ()`
, it will wait for the process to finish until the `wg.Done ()`
of the gorutine function is called.
By writing in this way, it is possible to prevent the process from ending without executing the goroutine function.
By the way, `wg.Add (1) ``` is waiting for the goroutine process to finish, so commenting out
wg.Done ()
`` will result in an error.
wg.After adding wg.Done()You need to call to indicate that the process is complete.
You can also write the goroutine function as follows:
```go
func goroutine(s string, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 5; i++ {
fmt.Println(s)
}
}
If you use the defer statement, wg.Done () will be executed after the function has finished processing, so you can write it like this.
If you have any mistakes or impressions, please comment! !!
Recommended Posts