1.goroutine
进程Process:操作系统中的执行过程、资源分配和调度的独立单位
线程Thread:是进程执行的实体,是CPU调度和分配的基本单位
协程coroutine:独立栈空间、共享堆空间、调度用户自己控制,是轻量级的线程
Go语言中支撑整个scheduler实现的主要有4个重要结构,分别是M、G、P、Sched, 前三个定义在runtime.h中,Sched定义在proc.c中。
1.Sched结构就是调度器,它维护有存储M和G的队列以及调度器的一些状态信息等。
2.M结构是Machine,系统线程,它由操作系统管理的,goroutine就是跑在M之上的;M是一个很大的结构,里面维护小对象内存cache(mcache)、当前执行的goroutine、随机数发生器等等非常多的信息。
3.P结构是Processor,处理器,它的主要用途就是用来执行goroutine的,它维护了一个goroutine队列,即runqueue。Processor是让我们从N:1调度到M:N调度的重要部分。
4.G是goroutine实现的核心结构,它包含了栈,指令指针,以及其他对调度goroutine很重要的信息,例如其阻塞的channel
runtime调度器
NumCpu:cpu核数
runtime.Gosched()当前线程让出cpu
runtime.Goexit()退出goroutine
runtime.GOMAXPROCS()设置最大盒数
runtime.GC强制回收一次
2.channel(通道)
var ch1 chan int
ch2:=make(chan int ,3)
close(ch)
三种操作:send/receive/close
两种特殊channel:nil channel和channal类型的channel。
当channel中没有数据可读时,goroutine将会阻塞在此行
for+select建议使用default/超时时间.否则发送数据时可能出现死锁
当关闭一个channel时,会使得这个channel变得可读
3.定时器
time.after(d)、Ticker(d);After(d)和NewTime(d).C是等价的。
timer1:=time.Newtimer()
<-timer.C
timer1.reset()
ticker:=time.newTicker()
4.并发安全与锁
互斥锁:lock.Lock()/locl.Unlock()
读写多rwlock.RLock() rwlock.RUnlock() rwlock.Lock() rwlock.Unlock()
5.Sync(同步包)
var wg sync.WaiteGroup
- Add():每次激活想要被等待完成的goroutine之前,先调用Add(),用来设置或添加要等待完成的goroutine数量
- Done():每次需要等待的goroutine在真正完成之前,应该调用该方法来人为表示goroutine完成了,该方法会对等待计数器减1
- Wait():在等待计数器减为0之前,Wait()会一直阻塞当前的goroutine
sync.onece
sync.map
原子操作:atomic
示例:
wg.Wait()
func process(i int, wg *sync.WaitGroup) {
fmt.Println("started Goroutine ", i)
time.Sleep(2 * time.Second)
fmt.Printf("Goroutine %d ended\n", i)
wg.Done()
}