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()
}