Rumah >pembangunan bahagian belakang >Golang >Mengapa Go Buat Sedikit Benang Apabila Banyak Goroutine Sekat pada Tulisan Fail Pantas?

Mengapa Go Buat Sedikit Benang Apabila Banyak Goroutine Sekat pada Tulisan Fail Pantas?

Susan Sarandon
Susan Sarandonasal
2024-12-16 06:02:11846semak imbas

Why Does Go Create Few Threads When Many Goroutines Block on Fast File Writes?

Mengapa Penciptaan Benang Minimum Berlaku dengan Penyekatan Tulisan Fail dalam Go

Dalam Go, apabila gorout terlibat dalam menyekat panggilan, benang biasanya dibuat untuk memudahkan operasi tersebut. Walau bagaimanapun, pemerhatian yang membingungkan timbul apabila berbilang goroutin disekat semasa cuba menulis ke fail. Walaupun terdapat banyak goroutine, bilangan benang yang terhad ditubuhkan.

Kod Ujian dan Pemerhatian

Skrip ujian berikut menunjukkan tingkah laku ini:

package main

import (
    "io/ioutil"
    "os"
    "runtime"
    "strconv"
)

func main() {
    runtime.GOMAXPROCS(2)
    data, err := ioutil.ReadFile("./55555.log")
    if err != nil {
        println(err)
        return
    }
    for i := 0; i < 200; i++ {
        go func(n int) {
            for {
                err := ioutil.WriteFile("testxxx"+strconv.Itoa(n), []byte(data), os.ModePerm)
                if err != nil {
                    println(err)
                    break
                }
            }
        }(i)
    }
    select {}
}

Ironisnya, apabila skrip ini dilaksanakan, hanya segelintir utas yang dicipta, seperti yang ditunjukkan oleh arahan:

$ cat /proc/9616/status | grep -i thread
Threads:    5

Menyelesaikan Teka-teki

Kunci untuk memahami tingkah laku ini terletak pada sifat operasi menyekat. Dalam ujian asal, penulisan fail sedang disiapkan terlalu pantas untuk mencetuskan penciptaan urutan baharu.

Untuk menggambarkan ini, skrip ujian telah diubah suai untuk menulis blok data yang lebih besar:

package main

import (
    "io/ioutil"
    "os"
    "runtime"
    "strconv"
)

func main() {
    runtime.GOMAXPROCS(2)
    data := make([]byte, 128*1024*1024)
    for i := 0; i < 200; i++ {
        go func(n int) {
            for {
                err := ioutil.WriteFile("testxxx"+strconv.Itoa(n), []byte(data), os.ModePerm)
                if err != nil {
                    println(err)
                    break
                }
            }
        }(i)
    }
    select {}
}

Pengubahsuaian ini menghasilkan penciptaan lebih 200 utas, seperti yang ditunjukkan oleh arahan:

$ cat /proc/17033/status | grep -i thread
Threads:    203

Kesimpulan

Oleh itu, apabila operasi menulis fail dilakukan dengan cepat, sifat menyekat panggilan mungkin tidak mencukupi untuk mencetuskan penciptaan berbilang benang. Hanya apabila operasi menyekat menjadi lebih ketara, keperluan untuk utas tambahan akan menjadi jelas, mengakibatkan percambahan benang seperti yang dijangkakan.

Atas ialah kandungan terperinci Mengapa Go Buat Sedikit Benang Apabila Banyak Goroutine Sekat pada Tulisan Fail Pantas?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn