摘要:
字符串 type _string struct { elements *byte // 引用着底层的字节 len int // 字符串中的字节数,获取长度O(1) } 对于字符串比较,编译器有两个优化: 若长度不相等,则字符串不相等,O(1) 若指针相等,长度大的字符串大,O(1) slice sl 阅读全文
摘要:
go newproc new newobject make makeslice,makechan,makemap,makemap_small...... <- chansend1,chanrecv1,chanrecv2 close closechan select selectgo make、new 阅读全文
摘要:
futex futex(&f, FUTEX_WAIT, val, t, nil, 0) 选项FUTEX_WAIT,表示使用mmap在内核态和用户态之间共享f的内存,测试f的值如果等于val则休眠时间t futex(&f, FUTEX_WAKE, cnt, nil, nil, 0) 选项FUTEX_W 阅读全文
摘要:
在执行调度循环 runtime.schedule 时,或者系统监控sysmon时,会检查是否有timer就绪。 每次把堆顶timer的when和当前时间作比较,when<nowtime则执行timer里的f,并删除当前timer,如果是ticker,则计算下一次触发的时间,加入到堆中 timer存放 阅读全文
摘要:
sync.Cond type Cond struct { L Locker notify notifyList } func NewCond(l Locker) *Cond { return &Cond{L: l} } func (c *Cond) Wait() { t := runtime_not 阅读全文
摘要:
接口 type Context interface { Deadline() (deadline time.Time, ok bool) //若实现了超时控制,该方法返回超时时间,true。否则ok为false Done() <-chan struct{} // 通过关闭channel进行通知 Er 阅读全文
摘要:
var x, y int go func() { x = 1 fmt.Print("y:", y, " ") }() go func() { y = 1 fmt.Print("x:", x, " ") }() 结果可能为 y:0 x:0 , 编译器看到打印和赋值的变量不同,认为交换两条语句不会影响结 阅读全文
摘要:
需要poll的文件描述符都被设置成非阻塞的,加入到epoll里,对应的pollDesc放到epoll event的data域中, 某个goroutine读写fd被阻塞时,runtime会把 fd 对应的 pollDesc 里的 rg / wg 字段设置为这个 g,然后将 g 放到系统的等待队列中 调 阅读全文
摘要:
CALL runtime·args(SB) // 整理命令行参数 CALL runtime·osinit(SB) // 确定cpu核心数 CALL runtime·schedinit(SB) // 初始化核心组件 CALL runtime·newproc(SB) // 创建主goroutine即ru 阅读全文
摘要:
启动m,进入调度循环 gosave初始化g0.sched执行现场,acquirep绑定p,schedule调度 mstart -> mstart1 -> save -> acquirep -> schedule -> mexit 休眠m gc时,或找不到g的m,或者因执行时间过长、系统调用阻塞等原因 阅读全文
摘要:
抢占的时机 gc时,抢占所有g 系统监控发现长时间阻塞于系统调用或者运行时间过长时,抢占该g 同步协作式调度 主动用户让权:通过 runtime.Gosched 主动让出执行机会; 主动调度弃权:当发生执行栈分段时,检查自身的抢占标记,决定是否继续执行; 异步抢占式调度 被动监控抢占:当 G 阻塞在 阅读全文
摘要:
锁定g和m 在执⾏ cgo 调⽤时,会⽤ lockOSThread 将 G 锁定在当前线程 锁定操作很简单,只需设置 G.lockedm 和 M.lockedg 即可 lockedm 会休眠,直到某⼈将 lockedg 交给它。⽽不幸拿到 lockedg 的 M, 则要将 lockedg 连同 P 阅读全文
摘要:
动态栈 栈是自动增长的,默认2KB,32位架构最大250M,64位架构最大1G,可用runtime/debug.SetMaxStack来设置 每次执行函数调用时Go的runtime都会进行检测,若当前栈的大小不够用,则会触发“中断”,从当前函数进入到Go的运行时库,Go的运行时库会保存此时的函数上下 阅读全文
摘要:
len 和 cap 调用 实参类型 结果 len(s) [n]T, *[n]T 数组长度(== n) []T 切片长度 chan T 信道缓存中元素队列的长度 map[K]T 映射长度(已定义键的数量) string type 字符串的字节长度 cap(s) [n]T, *[n]T 数组长度(== 阅读全文
摘要:
字符串内容不能更改,可包含byte值0,len()获取的是字节数量, s[i]返回第i个字节的值,类型是uint8,&s[i] 是非法的 s:=s1+s2 会创建一个新的字符串 t:=s[3:8] 不会创建一个新的字符串 //应该是创建了新的直接部分,而引用相同的底层数据 待验证 源码 for i, 阅读全文
摘要:
数组 数组是值,将一个数组变量赋值给另一个变量会复制其所有元素。将数组传入函数会复制其所有元素。可以传数组指针,但切片是更好的做法 数组的大小是其类型的一部分。类型 [10]int 和 [20]int 是不同的。长度必须为常量 长度为零的数组的尺寸为零;元素类型尺寸为零的任意长度的数组类型的尺寸也为 阅读全文
摘要:
map是引用类型,底层是哈希表,操作是常数时间的 复制map,新旧map共享同一个底层哈希表,在函数里对map进行操作,结果对调用者可见 var m map[int]string,m是nil,底层没有引用哈希表, 不能向nil值的map添加元素,其他大部分对nil值的map的操作都是合法的,行为类似 阅读全文
摘要:
形参(或结果)列表中,名称要么都存在,要么都不存在 指定了返回形参的名字,在进入函数时,返回值会被初始化为自身类型的零值 若所有的返回值都有名称,return语句可以省略操作数,这被称为bare return 若只有一个没有名称的结果,结果列表可以不加括号 未初始化的函数类型变量的值为nil,调用n 阅读全文
摘要:
type abc struct { x, y int u float32 "标注" _ float32 // padding A *[]int F func() } var a abc // 声明变量,会开辟一段内存 t := &a.x // 对成员取地址 . 的优先级比 * 和 & 高 // 用m 阅读全文
摘要:
接收者类型必须为形式 T 或 *T, T 称为接收者的 基础类型, 它不能为指针或接口类型 声明 func (p *Point) Scale(factor float64) {...} 将接收者类型为 *Point 的方法 Scale 绑定至基础类型 Point。 必须在同一包中声明方法。 给类型别 阅读全文