Maison >développement back-end >Golang >Pourquoi Go crée-t-il peu de threads alors que de nombreux Goroutines bloquent les écritures rapides de fichiers ?

Pourquoi Go crée-t-il peu de threads alors que de nombreux Goroutines bloquent les écritures rapides de fichiers ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-16 06:02:11839parcourir

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

Pourquoi la création minimale de threads se produit avec le blocage de l'écriture de fichiers dans Go

Dans Go, lorsque les goroutines bloquent les appels, les threads sont généralement créés pour faciliter de telles opérations. Cependant, une observation déroutante survient lorsque plusieurs goroutines sont bloquées lors d'une tentative d'écriture dans un fichier. Malgré la présence de nombreuses goroutines, un nombre limité de threads sont établis.

Code de test et observations

Le script de test suivant démontre ce comportement :

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 {}
}

Ironiquement, lorsque ce script est exécuté, seule une poignée de threads est créée, comme l'indique le commande :

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

Résoudre l'énigme

La clé pour comprendre ce comportement réside dans la nature de l'opération de blocage. Dans le test d'origine, les écritures de fichiers se terminent trop rapidement pour déclencher la création de nouveaux threads.

Pour illustrer cela, le script de test a été modifié pour écrire un bloc de données beaucoup plus volumineux :

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 {}
}

Cette modification a entraîné la création de plus de 200 fils de discussion, comme le montre le command :

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

Conclusion

Ainsi, lorsque les opérations d'écriture de fichiers sont effectuées rapidement, le caractère bloquant des appels peut ne pas être suffisant pour déclencher la création de plusieurs fils. Ce n'est que lorsque les opérations de blocage deviendront plus importantes que le besoin de threads supplémentaires deviendra apparent, entraînant la prolifération des threads comme prévu.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn