一、golang并发示例

1.1 无缓冲chan与缓冲chan

知识点:
无缓存chan:别的协程,有人读(<-)才能写成功,否则阻塞。
有缓冲chan:写满了后,再写,阻塞;读完了后,再读,阻塞。

代码(1无缓冲chan):

package main

import (
        "fmt"
)

func main() {
        ch := make(chan int)

        //ch <- 1

        go func() {
                fmt.Println(<- ch)
        }()

        ch <- 1

        fmt.Println("ok")
}

运行结果1:

[root@bogon 10]# go run test.go 
1
ok

去掉注释后的运行结果1:

[root@bogon 10]# go run test.go 
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
	/root/temp/go/10/test.go:10 +0x59
exit status 2

1.2 select、超时

知识点:
select每个case语句必须是一个IO操作。
select随机选择一个可运行的case。
select没有可运行的case,就会阻塞。

代码:

package main

import (
        "fmt"
        "time"
)

func main() {
        //
        ch := make(chan int)

        go func() {
                time.Sleep(3 * time.Second)
                ch <- 1
        }()

        //
        timeout := make(chan int)

        go func() {
                time.Sleep(2 * time.Second)
                timeout <- 2
        }()

        //
        fmt.Println("start:", time.Now().String())
        select {
                case <- ch:
                        fmt.Println("ok")
                case <- timeout:
                        fmt.Println("timeout")
                //case <- time.After(time.Duration(1 * time.Second)):
                //      fmt.Println("timeout!!!")
        }
        fmt.Println("end:", time.Now().String())

}

运行结果:

[root@bogon 10]# go run test.go 
start: 2020-10-12 20:12:28.96981769 +0800 CST m=+0.000079718
timeout
end: 2020-10-12 20:12:30.970510619 +0800 CST m=+2.000772764