goroutine
在go语言中,每一个并发的执行单元叫做一个goroutine
这里说到并发,所以先解释一下并发和并行的概念:
- 并发:逻辑上具备同时处理多个任务的能力
- 并行:物理上在同一时刻执行多个并发任务
当一个程序启动时,其主函数即在一个单独的goroutine中运行,一般这个goroutine是主goroutine;如果想要创建新的goroutine,只需要再执行普通函数或者方法的的前面加上关键字go。
通过下面一个例子演示并发的效果,主goroutine会计算第45个斐波那契函数,在计算的同时会循环打印:-|/
这里需要知道:当主goroutine结束之后,所有的goroutine都会被打断,程序就会退出
package main
import (
"time"
"fmt"
)
func spinner(delay time.Duration){
for {
for _,r := range `-\|/`{
fmt.Printf("\r%c",r)
time.Sleep(delay)
}
}
}
func fib(x int) int{
// 斐波那契函数
if x < 2{
return x
}
return fib(x-1) + fib(x-2)
}
func main() {
go spinner(100*time.Millisecond) //开启一个goroutine
const n = 45
fibN:= fib(n)
fmt.Printf("\rFib(%d) = %d\n",n,fibN)
}
go语句直接开启协程是不是很清爽?我们看一下网络编程方面的例子:
Server端
package main
import (
"net"
"io"
"time"
"log"
)
func handleConn(c net.Conn){
defer c.Close()
for{
_,err := io.WriteString(c,time.Now().Format("15:04:05\r\n"))
if err != nil{
return
}
time.Sleep(1*time.Second)
}
}
func main() {
// 监听本地tcp的8000端口
listener,err := net.Listen("tcp","localhost:8000")
if err != nil{
log.Fatal(err)
}