在GO语言中,每一个并发执行的活动称为goroutine。这个概念听起来有些抽象,通俗点来讲,goroutine就是每一个并发执行的函数或者方法。一个goroutine通过go语句来创建。程序启动时通过main函数进行,main函数就是主goroutine。需要注意的是,如果主goroutine执行完成时。其它goroutine直接终结,不管其有没有执行完毕。下面通过一段代码来看一下:
// demo project main.go
package main
import (
"fmt"
"time"
)
func testGoroutine() {
fmt.Println("Hello World")
}
func main() {
go testGoroutine()
go testGoroutine()
go testGoroutine()
time.Sleep(1 * time.Second)
}
执行结果
但是如果将time.Sleep注释掉,那么执行结果为:
这时因为主goroutine执行结束时,其它的goroutine没有执行结束,所以其它的goroutine直接结束。
上一篇博客中我们写了一个简单的聊天程序,但是程序只能由一个客户端,这里我们学习了并发以后,我们将其修改,可以执行多个客户端。所有代码就不全部列出了,这里只列出修改的地方:
// stydy project main.go
package main
import (
"fmt"
"log"
"net"
"time"
)
func startServer() {
listener, err := net.Listen("tcp", "127.0.0.1:12031")
defer listener.Close() //延迟关闭监听
if err != nil {
fmt.Println(err)
}
for {
conn, err := listener.Accept()
if err != nil {
fmt.Println(err)
continue
}
go receiveAndSendMsg(conn)
//time.Sleep(1 * time.Second)
}
}
func receiveAndSendMsg(conn net.Conn) {
defer conn.Close()
log.Println(conn.RemoteAddr().String())
buffer := make([]byte, 50)
for {
conn.Write([]byte("hi client, i am server:" + time.Now().Format("15:04:05")))
_, err := conn.Read(buffer)
if err != nil {
return
}
log.Printf("msg is : %v\n", string(buffer))
//time.Sleep(1 * time.Second)
}
}
func main() {
startServer()
}
很简单,在server端收发消息的函数前加上关键字go就可以了。但是这里又存在了一个问题,现在理论上可以有无限多个客户端,如果现在要求只能连接20个客户端,如果超出20个,其余客户端等待连接,这个要怎么实现呢。这个就需要下一篇博客讲的通道的知识了。