Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah rutin pergi berkelakuan seperti ini?

Mengapakah rutin pergi berkelakuan seperti ini?

WBOY
WBOYke hadapan
2024-02-08 23:30:10711semak imbas

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

editor php Xigua akan menjawab soalan anda tentang "sebab tingkah laku rutin pergi". Rutin (goroutine) dalam bahasa Go ialah mekanisme serentak ringan yang boleh mencapai kesan pelaksanaan serentak. Walau bagaimanapun, dalam beberapa kes, tingkah laku rutin pergi mungkin mempunyai beberapa hasil yang tidak dijangka. Ini disebabkan terutamanya oleh mekanisme penjadualan rutin pergi dan ciri-ciri model ingatan. Sebelum kita memahami dengan mendalam gelagat rutin bahasa Go, kita perlu memahami ciri ini dan kesannya terhadap gelagat program.

Kandungan soalan

Saya sedang membaca buku berjudul "Go in action" dan saya agak keliru tentang bahagian goroutine buku itu, pada dasarnya saya ingin tahu dua perkara tentang kod berikut:

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()
}

Keluaran ialah:

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. Mengapa ia melaksanakan goroutine B terlebih dahulu? Kerana dalam kod goroutine A didahulukan, saya mahu ia dijalankan dahulu juga.
  2. goroutine B menggunakan kaedah .Gosched untuk membiarkan goroutine A mula melaksanakan, tetapi memandangkan mutex dikunci, goroutine A akan menunggu untuk dibuka kuncinya. Pada masa ini, saya menetapkan GOMAXPROCS untuk mempunyai hanya satu pemproses logik Mengapa nampaknya kedua-dua goroutine berjalan selari? Adakah ini benar-benar berlaku?

Seperti yang saya katakan, menetapkan gomaxprox kepada 1 akan membenarkan hanya satu Goroutine untuk dilaksanakan pada satu masa, tetapi dalam kes ini, itu nampaknya tidak berlaku, sebenarnya kedua-dua Goroutine berjalan secara selari.

Penyelesaian

Gorutin berjalan serentak. Ini bermakna jika terdapat pemproses yang tersedia, penjadual boleh menjadualkannya untuk dijalankan secara selari. Jika hanya satu pemproses tersedia, mereka akan tetap berjalan serentak, tetapi hanya satu goroutine akan berjalan pada bila-bila masa.

Waktu jalan Go tidak memberi jaminan tentang goroutine mana yang akan dijalankan dahulu. Jadi susunan larian set goroutine yang baru dibuat adalah rawak,

Atas ialah kandungan terperinci Mengapakah rutin pergi berkelakuan seperti ini?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam
Artikel sebelumnya:Gin Gonic - kolon dalam URLArtikel seterusnya:Gin Gonic - kolon dalam URL