首頁  >  文章  >  後端開發  >  為什麼 go 例程會有這樣的行為?

為什麼 go 例程會有這樣的行為?

WBOY
WBOY轉載
2024-02-08 23:30:10758瀏覽

为什么 go 例程会有这样的行为?

php小編西瓜為您解答關於"go 程式行為的原因"的問題。 go語言中的例程(goroutine)是一種輕量級的並發機制,可以實現並發執行的效果。然而,在某些情況下,go例程的行為可能會出現一些意料之外的結果。這主要是因為go例程的調度機制以及記憶體模型的特性所導致的。在深入理解go語言的例程行為之前,我們需要先了解這些特性以及它們對程式行為的影響。

問題內容

我正在讀一本叫做《Go in action》的書,我對書中的goroutine 部分感到有點困惑,基本上我想了解有關以下程式碼的兩件事:

package main

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

var counter int = 0
var wg sync.WaitGroup
var mtx sync.Mutex

func main() {
    wg.Add(2)

    runtime.GOMAXPROCS(1)

    go incCounter("A")
    go incCounter("B")

    wg.Wait()
    fmt.Println(counter)
}

func incCounter(prefix string) {
    fmt.Println("Started thread ", prefix)
    defer wg.Done()
    mtx.Lock()
    {
        fmt.Println("Incrementing counter from ", prefix)
        counter = counter + 1
        fmt.Println("Passing to another thread")
        runtime.Gosched()
        for i := 1; i < 100; i++ {
            time.Sleep(1 * time.Second)
            fmt.Println("Thread still executing ", prefix)
        }
    }
    mtx.Unlock()
}

輸出為:

Started thread  B
Incrementing counter from  B
Passing to another thread
Started thread  A
Thread still executing  B
Thread still executing  B
Thread still executing  B
Thread still executing  B
  1. 為什麼它先執行goroutine B?因為在程式碼中 goroutine A 首先出現,所以我希望它也先運行。
  2. goroutine B 使用 .Gosched 方法讓 goroutine A 開始執行,但由於互斥體被鎖定,goroutine A 將等待解鎖。此時我將GOMAXPROCS設定為只有一個邏輯處理器,為什麼看起來兩個goroutine是並行運作的呢?這真的應該發生嗎?

正如我所言,將 gomaxprox 設為 1 將允許一次只執行一個 Goroutine,但在這種情況下,似乎並不是這樣,實際上兩個 Goroutine 都在並行運行。

解決方法

Goroutines 並發運行。這意味著,如果有可用的處理器,調度程序可以安排它們並行運行。如果只有一個處理器可用,它們仍然會並發運行,但在任何給定時刻只有一個 goroutine 運行。

Go 運行時不保證哪個 goroutine 會先運行。所以一組新創建的goroutine的運行順序是隨機的,

以上是為什麼 go 例程會有這樣的行為?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除