go語言--競爭、原子函數、互斥鎖

1、go語言競爭狀態、原子函數、互斥鎖

下面代碼例子是展現併發下公共數據操做,經過原子函數和互斥鎖怎麼解決。安全

package main

import (
    "sync"
    "runtime"
    "fmt"
    "sync/atomic"
)

var(
    // counter是全部goroutine都要增長的變量
    counter int64
    // wg用來等待程序的結束
    wg sync.WaitGroup
    // mutex 用來定義一段代碼臨界區
    mutex sync.Mutex
)

func main() {
    // 計數加2,表示要等待兩個goroutine
    wg.Add(2)
    // 建立兩個goroutine
    go incCounter(1)
    go incCounter(2)
    // 等待goroutine結束
    wg.Wait()
    fmt.Println("Final Counter:", counter)
}

// incCounter增長包裏counter變量的值
func incCounter(id int) {
    // 延時調用,在函數退出時調用Done來通知main函數工做已經完成
    defer wg.Done()

    for count := 0; count < 2; count++ {
        // 捕獲counter的值
        value := counter
        // 當前goroutine從線程退出,並放回到隊列
        runtime.Gosched()
        // 增長本地value變量的值
        value++
        // 將該值保存回counter
        counter = value
    }
}
// incCounter增長包裏counter變量的值
func incCounter1(id int) {
    defer wg.Done()

    for count := 0; count < 2; count++ {
        // 安全的對counter加1
        atomic.AddInt64(&counter, 1)
        // 當前goroutine從線程退出,並放回到隊列
        runtime.Gosched()
    }
}

// incCounter增長包裏counter變量的值
func incCounter2(id int) {
    // 延時調用,在函數退出時調用Done來通知main函數工做已經完成
    defer wg.Done()

    for count := 0; count < 2; count++ {
        // 同一時刻只容許一個goroutine進入這個臨界區
        mutex.Lock()
        {
            // 捕獲counter的值
            value := counter
            // 當前goroutine從線程退出,並放回到隊列
            runtime.Gosched()
            // 增長本地value變量的值
            value++
            // 將該值保存回counter
            counter = value
        }
        // 釋放鎖,容許其餘正在等待的goroutine進入臨界區
        mutex.Unlock()
    }
}
  • 下面圖片是競爭狀態下的數據交互模型

相關文章
相關標籤/搜索