Golang多線程初識-day26-goroutine通信-線程同步(sync)

全局變量和鎖(sync)

  • 透過全局的數據結構達到線程之間的通信
  • 建立互斥鎖(sync.Mutex) -> 只會有一個線程進到程序中進行讀寫
  • 透過go build -race 檔名查看是否存在資源的競爭

example

  • 創建goroutine完成不同數階乘的計算
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    package main

    import (
    "fmt"
    "time"
    "sync"
    )

    type task struct {
    num int
    }

    //創建一個為map[string]int類型的切片
    var ShareSlice []map[string]int = make([]map[string]int,0)
    var lock sync.Mutex

    func calc(t *task){
    result := 1

    //進行階乘運算
    for i:=1; i<=t.num; i++{
    result *= i
    }
    var ans map[string]int = map[string]int{fmt.Sprintf("%d!",t.num):result}

    //涉及多個goroutine對同一個slice進行寫操作,因此加鎖
    lock.Lock()
    ShareSlice = append(ShareSlice,ans)
    lock.Unlock()
    }

    func main(){

    //創建多個goroutine
    for i:=1;i<11;i++{
    t := &task{num:i}
    go calc(t)
    }

    //讓主線程等待所有線程完成執行計算任務
    time.Sleep(time.Second*5)

    //對同一數據進行讀操作因此需加鎖
    lock.Lock()
    for _,v := range(ShareSlice){
    fmt.Println(v)
    }
    lock.Unlock()
    }

result

1
2
3
4
5
6
7
8
9
10
map[9!:362880]
map[2!:2]
map[10!:3628800]
map[1!:1]
map[4!:24]
map[3!:6]
map[5!:120]
map[7!:5040]
map[6!:720]
map[8!:40320]

tips

  • 可搭配 Go初識-day13-包(package)、線程同步(sync)與atomic操作 一起服用