首頁  >  文章  >  後端開發  >  Golang函數參數傳遞中的並發併發症

Golang函數參數傳遞中的並發併發症

王林
王林原創
2024-04-13 18:54:01531瀏覽

在並發 Goroutine 修改共享參數情況下,Go 函數參數傳遞有以下規則:按值傳遞:副本傳遞給函數,更改副本不影響原始值。按引用傳遞:指標傳遞給函數,更改指標值會同時修改原始值。按引用傳遞時,多個 Goroutine 同時修改參數可導致併發併發症。在共享資料並發的場景中,應謹慎使用按引用傳遞,並結合適當的並發控制措施。

Golang函數參數傳遞中的並發併發症

Go 函數參數傳遞中的同時併發症

在 Go 中,函數參數可以按值傳遞或按引用傳遞。當按值傳遞時,參數的副本會傳遞給函數,而當按引用傳遞時,對參數的修改將反映在呼叫函數中。

然而,在並發環境中,這種參數傳遞模式可能會導致並發併發症,因為多個並發執行的 Goroutine 可能會同時修改相同參數。

按值傳遞

func modifyInt(i int) {
    i++ // 只修改 i 变量的副本
}

func main() {
    i := 0
    go modifyInt(i)
    fmt.Println(i) // 输出 0(原始值)
}

在按值傳遞的情況下,儘管modifyInt() 函數修改了傳遞給它的i 的副本,但呼叫函數中的原始i 變數不受影響。

按引用傳遞

func modifyIntPointer(i *int) {
    *i++ // 修改 i 变量的实际值
}

func main() {
    i := 0
    go modifyIntPointer(&i)
    fmt.Println(i) // 输出 1(修改后的值)
}

在按引用傳遞的情況下,對指向原始 i 變數的指標參數的修改將反映在呼叫函數中。這可能會導致併發併發症,因為多個 Goroutine 可能會同時修改相同參數。

實戰案例

考慮以下讀寫鎖定案例,它保護對共享資料的並發存取。

type MutexMap struct {
    m map[string]int
    mu sync.Mutex // 互斥锁
}

func (m *MutexMap) Get(key string) int {
    m.mu.Lock() // 加锁
    defer m.mu.Unlock() // 解锁(延迟执行)
    return m.m[key]
}

func (m *MutexMap) Set(key string, value int) {
    m.mu.Lock()
    defer m.mu.Unlock()
    m.m[key] = value
}

如果 MutexMapm 欄位是按引用傳遞的,則多個 Goroutine 可能會同時加鎖,從而導致死鎖。

結論

在並發環境中,了解函數參數傳遞模式及其對共享資料的潛在影響非常重要。按值傳遞通常更安全,而按引用傳遞應該謹慎使用,並與適當的並發控制措施結合使用。

以上是Golang函數參數傳遞中的並發併發症的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn