1.主协程(main协程)退出后,子协程会相继退出,这个是如果主协程不阻塞看不到子协程打印结果的原因。
2.runtime.Goexit()函数用于终止当前 goroutine,但 defer 函数将会被继续调用。
3.GOMAXPROCS(n int) int 用来设置可同时运行的线程数,并返回当前设置的值,如果 n<1 将不会改变当前的设置。NumCPU()返回当前的CPU核数,通常这样使用:
runtime.GOMAXPROCS(runtime.NumCPU())
4.并发和并行是两个概念。并发是对单核进行轮询执行,并行是多核平行执行。
5.匿名函数的调用记得加上括号。
defer func (){
fmt.Println("Hello Man")
}()
6.Goroutine 之间通过 channel 来通讯,可以认为 channel 是一个管道或者先进先出的队列。你可以从一个 goroutine 中向 channel 发送数据,在另一个 goroutine 中取出这个值。生产者/消费者是最经典的 channel 使用示例。协程消费者在没有接收到数据前,是阻塞的。
7.channel 可以是多种数据类型。生产者直到数据被消费者取走后才能发送下一条数据;channel 的消费者直到生产者放入数据后继续取数据。正是这种机制,才保证数据的不会错乱,从而实现同步。
8.Go 里的定时器相关的函数有 time.After,time.AfterFunc,time.Tick .
- c := time.After(10 * time.Second)
//返回 channel 类型,10秒后向 channel 发送当前时间
t := <-c
- time.AfterFunc(10*time.Second, Test),等待时间 10秒,然后调用函数 test。注意这里的函数 f 是不带任何参数和返回值的.
- Tick 与 After 有点类似,唯的区别是 After 等待时间到期后,定时器就结束了。Tick 是每隔一段时间 d 都会向 channel 发送当前时间。说到底,tick就是一个定时任务器。
9.Golang 可以在任何平台上开发,只要到目标平台上编译即可。我们所需要做的就是复制交叉编译的二进制文件来实现可移植性。
10.Gin是一个MVC的web开发框架,跟PHP的传统框架很相似。
11.如果两个或者多个 goroutine 在没有互相同步的情况下,访问某个共享的资源,并试图同时 读和写这个资源,就处于相互竞争的状态,这种情况被称作竞争状态(race candition)。竞争状态 的存在是让并发程序变得复杂的地方,十分容易引起潜在问题。对一个共享资源的读和写操作必 须是原子化的,换句话说,同一时刻只能有一个 goroutine 对共享资源进行读和写操作。