我们先来看一个简单的并发实例:
package main
import (
"fmt"
"time"
)
func run(task_id, sleeptime int, ch chan string) {
time.Sleep(time.Duration(sleeptime) * time.Second)
ch <- fmt.Sprintf("task id %d , sleep %d second", task_id, sleeptime)
return
}
func main() {
input := []int{3, 2, 1}
ch := make(chan string)
startTime := time.Now()
fmt.Println("Multirun start")
for i, sleeptime := range input {
go run(i, sleeptime, ch)
}
for range input {
fmt.Println(<-ch)
}
endTime := time.Now()
fmt.Printf("Multissh finished. Process time %s. Number of tasks is %d", endTime.Sub(startTime), len(input))
}
函数run()接受输入的参数,sleep若干秒。然后通过go关键字并发执行,通过channel返回结果。
channel就是goroutine之间通信的“管道”。管道中的数据流通,实际上是goroutine之间的一种内存共享。我们通过它可以在goroutine之间交互数据。
ch <- xxx //向channel写入数据
<- ch //从channel中读取数据
channel分为无缓冲(unbuffered)和缓冲(buffered)两种。例如刚才我们通过如下方式创建一个无缓冲的channel。
ch := make(chan string)
输出结果:
Multirun start
task id 2 , sleep 1 second
task id 1 , sleep 2 second
task id 0 , sleep 3 second
Multissh finished. Process time 3s. Number of tasks is 3
Program exited.
三个goroutine分别sleep了3,2,1秒。但总耗时只有3秒。所以并发生效了,go的并发就是这么简单。
package main
import (
"fmt"
"time"
)
func run(task_id, sleeptime int, ch chan string) {
time.Sleep(time.Duration(sleeptime) * time.Second)
ch <- fmt.Sprintf("task id %d , sleep %d second", task_id, sleeptime)
return
}
func main() {
input := []int{3, 2, 1}
chs := make([]chan string, len(input))
startTime := time.Now()