go之channel資料結構及方法

2021-09-11 01:56:37 字數 2075 閱讀 5526

// channel 型別定義

type hchan struct

// 等待佇列的鍊錶實現

type waitq struct

// in src/runtime/runtime2.go

// 對 go協程 的封裝

type sudog struct

func chansend(c *hchan, ep unsafe.pointer, block bool, callerpc uintptr) bool 

gopark(nil, nil, "chan send (nil chan)", traceevgostop, 2)

throw("unreachable")

}...

if !block && c.closed == 0 && ((c.dataqsiz == 0 && c.recvq.first == nil) ||

(c.dataqsiz > 0 && c.qcount == c.dataqsiz))

var t0 int64

if blockprofilerate > 0

lock(&c.lock)

if c.closed != 0

//有 goroutine 阻塞在 channel 上,此時 hchan.buf 為空:直接將資料傳送給該 goroutine。

if sg := c.recvq.dequeue(); sg !=

send(c, sg, ep, func() , 3)

return true

}//當前 hchan.buf 還有可用空間:將資料放到 buffer 裡面。

if c.qcount < c.dataqsiz

typedmemmove(c.elemtype, qp, ep)

c.sendx++

if c.sendx == c.dataqsiz

c.qcount++

unlock(&c.lock)

return true

}if !block

//當前 hchan.buf 已滿:阻塞當前 goroutine,gopark。

gp := getg()

mysg := acquiresudog()

mysg.releasetime = 0

if t0 != 0

// no stack splits between assigning elem and enqueuing mysg

// on gp.waiting where copystack can find it.

mysg.elem = ep

mysg.waitlink = nil

mysg.g = gp

mysg.selectdone = nil

mysg.c = c

gp.waiting = mysg

gp.param = nil

c.sendq.enqueue(mysg)

goparkunlock(&c.lock, "chan send", traceevgoblocksend, 3)

if mysg != gp.waiting

gp.waiting = nil

if gp.param == nil

panic(plainerror("send on closed channel"))

}gp.param = nil

if mysg.releasetime > 0

mysg.c = nil

releasesudog(mysg)

return true

}func send(c *hchan, sg *sudog, ep unsafe.pointer, unlockf func(), skip int)

gp := sg.g

unlockf()

gp.param = unsafe.pointer(sg)

if sg.releasetime != 0

goready(gp, skip+1)//importment

}

大致流程同上

go實現 資料結構之棧

寫在最後的話 先入後出 可以聯想成蒸包子的現象 其實出棧的話,就利用了golang的切片了,因為是 先出,所以只需要擷取切片就可以了 題目描述 leetcode1047給出由小寫字母組成的字串 s,重複項刪除操作會選擇兩個相鄰且相同的字母,並刪除它們。在 s 上反覆執行重複項刪除操作,直到無法繼續刪...

資料結構之GO實現環形佇列

環形佇列是 佇列的一種特殊形式。首先介紹佇列,然後引申出迴圈佇列。佇列又稱為 先進先出 fifo 線性表 限定插入操作只能在隊尾進行,而刪除操作只能在隊首進行 佇列也可以採用順序儲存結構或鍊錶結構來實現,分別稱為順序佇列和鏈佇列,下面就來簡單實現。package main import errors...

資料結構之Go實現單鏈表

單向鍊錶是一種線性表,實際上是由節點組成的,乙個鍊錶擁有不定數量的節點。其資料在記憶體中儲存是不連續的,它儲存的資料分散在記憶體中,每個結點只能也只有它能知道下乙個結點的儲存位置。由n各節點 node 組成單向鍊錶,每乙個node記錄本node的資料及下乙個node。向外暴露的只有乙個頭節點 hea...