当程序发生崩溃时只会调用当前 Goroutine 的延迟调用函数也是非常合理的
在其他goroutine中发生panic不recover,会导致整个程序退出(不仅仅是退出该问题goroutine)
当前gorotuinepanic,必须在当前goroutine recover
下面这段代码会发生什么? (为什么不输出 in main ?)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package main import ( "time" ) func main() { defer println("in main") go func() { defer println("in goroutine ") panic("") }() time.Sleep(1 * time.Second) } 下面这段代码输出什么? (recover要放在defer里)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package main import ( "fmt" ) func main() { defer fmt....
make 的作用是初始化内置的数据结构,也就是我们在前面提到的切片、哈希表和 Channel2; new 的作用是根据传入的类型分配一片内存空间并返回指向这片内存空间的指针3;
上下文 context.Context Go 语言中用来设置截止日期、同步信号,传递请求相关值的结构体
树形结构
context与goroutine树
context 包中最常用的方法还是 context.Background、context.TODO,这两个方法都会返回预先初始化好的私有变量 background 和 todo,它们会在同一个 Go 程序中被复用
这两个私有变量都是通过 new(emptyCtx) 语句初始化的,它们是指向私有结构体 context.emptyCtx 的指针,这是最简单、最常用的上下文类型:
这两个变量都是emptyCtx类型,这个两个context,永远不会取消,没有value,没有deadline
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 type emptyCtx int func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { return } func (*emptyCtx) Done() <-chan struct{} { return nil // 意味着永不退出? } func (*emptyCtx) Err() error { return nil } func (*emptyCtx) Value(key interface{}) interface{} { return nil } context....
同步包sync
Mutex 8字节
1 2 3 4 5 type Mutex struct { state int32 sema uint32 } 互斥锁的状态比较复杂,如下图所示,最低三位分别表示 mutexLocked、mutexWoken 和 mutexStarving,剩下的位置用来表示当前有多少个 Goroutine 在等待互斥锁的释放
在默认情况下,互斥锁的所有状态位都是 0
正常模式 和 饥饿模式 在正常模式下,锁的等待者会按照先进先出的顺序获取锁。但是刚被唤起的 Goroutine 与新创建的 Goroutine 竞争时,大概率会获取不到锁,为了减少这种情况的出现,一旦 Goroutine 超过 1ms 没有获取到锁,它就会将当前互斥锁切换饥饿模式,防止部分 Goroutine 被『饿死』。
在饥饿模式中,互斥锁会直接交给等待队列最前面的 Goroutine。新的 Goroutine 在该状态下不能获取锁、也不会进入自旋状态,它们只会在队列的末尾等待。如果一个 Goroutine 获得了互斥锁并且它在队列的末尾或者它等待的时间少于 1ms,那么当前的互斥锁就会切换回正常模式。
如何从饥饿模式切换到正常模式 加锁和解锁 当锁的状态是 0 时,将 mutexLocked 位置成 1
如果互斥锁的状态不是 0 时就会调用 sync.Mutex.lockSlow 尝试通过自旋(Spinnig)等方式等待锁的释放,该方法的主体是一个非常大 for 循环,这里将它分成几个部分介绍获取锁的过程:
判断当前 Goroutine 能否进入自旋; 通过自旋等待互斥锁的释放; 计算互斥锁的最新状态; 更新互斥锁的状态并获取锁; 自旋是一种多线程同步机制,当前的进程在进入自旋的过程中会一直保持 CPU 的占用,持续检查某个条件是否为真。在多核的 CPU 上,自旋可以避免 Goroutine 的切换,使用恰当会对性能带来很大的增益,但是使用的不恰当就会拖慢整个程序,所以 Goroutine 进入自旋的条件非常苛刻:...
模式schema 在mysql中,schema是database的同义词
模式可以用来描述数据库中特定的表以及整个数据库和其中表的关系
表具有一些特性,这些特性定义了数据在表中如何存储,描述表的这组信息就是所谓的模式。
选择数据库 1 use db_name; 列出所有的数据库 1 show databases; 显示当前数据库中所有的表 1 show tables; 显示表的列 1 show columns from tb_name; 等价于
1 describe tb_name; 显示服务器状态信息 1 show status; 显示授权用户的相关信息 1 show grants; 显示服务器错误或警告 1 2 show errors; show warnings; 显示数据库或数据表的创建语句 1 2 show create database db_name; show create table tb_name;