Go語言實現執行緒安全訪問佇列
阿新 • • 發佈:2018-12-30
這個例子用Go語言的包"container/list"實現一個執行緒安全訪問的佇列。其中不少細節耐人尋味,做出它則是花費了不少精力,找不到樣例啊!
Go語言的許多優點自不必說,然而從C/C++程式角度看,語言的語法也好,程式的實現方式也好,看起來總有點怪怪的感覺。
在這個程式的基礎上,是很容易實現一個執行緒安全訪問的堆疊的。
Go語言程式:
// structlist project main.go package main import ( "container/list" "fmt" "sync" ) const N int = 10 type QueueNode struct { figure int digits1 [N]int digits2 [N]int sflag bool data *list.List } var lock sync.Mutex func newQueue() *QueueNode { q := new(QueueNode) q.data = list.New() return q } func (q *QueueNode) push(v interface{}) { defer lock.Unlock() lock.Lock() q.data.PushFront(v) } func (q *QueueNode) dump() { for iter := q.data.Back(); iter != nil; iter = iter.Prev() { fmt.Println("item:", iter.Value) } } func (q *QueueNode) pop() interface{} { defer lock.Unlock() lock.Lock() iter := q.data.Back() v := iter.Value q.data.Remove(iter) return v } func main() { var n QueueNode n.figure = 1 n.digits1[0] = 1 n.digits2[0] = 1 n.sflag = true n2 := n n2.digits1[n2.figure] = 2 n2.digits2[n2.figure] = 2 n2.figure++ n2.sflag = false n3 := n2 n3.digits1[n2.figure] = 3 n3.digits2[n2.figure] = 4 n3.figure++ q := newQueue() q.push(n) q.push(n2) q.push(n3) q.dump() fmt.Printf("\nlen=%d\n\n", q.data.Len()) for q.data.Len() > 0 { x := q.pop().(QueueNode) output_node(&x) } } func output_node(n *QueueNode) { fmt.Printf("Figure =%d\n", n.figure) fmt.Printf("Array1: ") for i := n.figure - 1; i >= 0; i-- { fmt.Printf("%d ", n.digits1[i]) } fmt.Println("") fmt.Printf("Array2: ") for i := n.figure - 1; i >= 0; i-- { fmt.Printf("%d ", n.digits2[i]) } fmt.Println("") if n.sflag { fmt.Printf("SFlag=true\n") } else { fmt.Printf("SFlag=false\n") } fmt.Println("") }
程式執行結果:
item: {1 [1 0 0 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0 0 0] true <nil>} item: {2 [1 2 0 0 0 0 0 0 0 0] [1 2 0 0 0 0 0 0 0 0] false <nil>} item: {3 [1 2 3 0 0 0 0 0 0 0] [1 2 4 0 0 0 0 0 0 0] false <nil>} len=3 Figure =1 Array1: 1 Array2: 1 SFlag=true Figure =2 Array1: 2 1 Array2: 2 1 SFlag=false Figure =3 Array1: 3 2 1 Array2: 4 2 1 SFlag=false
程式說明:
1.介面型別轉結構型別,花費了好多時間,其做法堪稱一絕,見79行。
2.全域性變數lock是佇列訪問鎖。
3.佇列使用來資源鎖,設計成執行緒安全訪問的。
4.程式中並沒有使用goroutine,如果需要可以使用類似這樣的程式碼"go func() { q.push(n) }()"