Maison  >  Article  >  développement back-end  >  time.Sleep() bloque-t-il vraiment les Goroutines et la gestion des threads d'impact dans le planificateur Go ?

time.Sleep() bloque-t-il vraiment les Goroutines et la gestion des threads d'impact dans le planificateur Go ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-20 00:22:03965parcourir

Does time.Sleep() Truly Block Goroutines and Impact Thread Management in the Go Scheduler?

Goroutines et gestion des threads avec time.Sleep()

Dans Go, les goroutines sont des threads légers gérés par le planificateur d'exécution. Une fonction couramment utilisée pour contrôler l'exécution de la goroutine est time.Sleep(), qui bloque l'exécution de la goroutine actuelle pendant une durée spécifiée. Cependant, cela soulève la question de savoir si time.Sleep() bloque réellement les goroutines et affecte la gestion des threads dans le planificateur Go.

Comprendre le blocage des goroutines

Oui, le temps. Sleep() bloque les goroutines. Lorsqu'il est appelé, il suspend l'exécution de la goroutine actuelle pendant la durée spécifiée. Pendant ce temps, la goroutine ne peut effectuer aucune opération ni répondre aux événements.

Thread Creation et time.Sleep()

Le nombre de threads créés dans un processus Go est influencé par divers facteurs, notamment les cœurs de processeur disponibles, le paramètre GOMAXPROCS et la charge de travail. Lorsque time.Sleep() est utilisé, cela ne conduit pas nécessairement à la création de nouveaux threads.

Le planificateur d'exécution Go exploite le « modèle MPG » (processus multiples, goroutines multiples) pour gérer les goroutines et les threads. Dans ce modèle, M (plusieurs) goroutines partagent P (plusieurs) threads. Lorsqu'une goroutine se bloque, le thread P associé peut être libéré pour desservir d'autres goroutines.

Exemple d'analyse de code

Examinons l'exemple de code fourni :

import (
    "runtime"
    "time"
)

func main() {
    runtime.GOMAXPROCS(4)
    ch := make(chan int)
    n := 1
    for i := 0; i < n; i++ {
        go func() {
            time.Sleep(60 * time.Second)
            ch <- 1
        }()
    }
    for i := 0; i < n; i++ {
        <-ch
    }
}

Dans cet exemple :

  • Nous définissons GOMAXPROCS sur 4, ce qui limite le nombre de threads actifs à 4.
  • Nous créons n goroutines, où chaque goroutine dort pendant 60 secondes, puis envoie une valeur à un canal.
  • Nous attendons que chaque goroutine se termine en recevant des valeurs du canal.

Lorsque n vaut 1, nous observons 5 threads dans le processus, en garantissant qu'il y a au moins un thread pour chaque goroutine en cours d'exécution. À mesure que n augmente, le nombre de threads reste relativement faible car le planificateur gère efficacement les threads P pour desservir plusieurs goroutines bloquées.

Différence avec les E/S explicites

Dans le deuxième exemple fourni :

import (
    "fmt"
    "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 {
                    fmt.Println(err)
                    break
                }
            }
        }(i)
    }
    select {}
}

Nous créons 200 goroutines qui écrivent en continu dans des fichiers. Dans ce cas, même si les goroutines ne sont pas explicitement bloquées avec time.Sleep(), les opérations d'E/S provoquent le blocage des goroutines, conduisant à la création de davantage de threads (202 dans cet exemple). Cela met en évidence l'impact des opérations non bloquantes sur la création de threads.

Conclusion

Le planificateur d'exécution Go gère efficacement la création de threads et l'exécution de goroutines. time.Sleep() bloque les goroutines, mais le nombre de threads créés est dynamique et influencé par la charge de travail. Les développeurs ne devraient pas se soucier de la gestion des threads, à moins qu'ils ne rencontrent des conditions extrêmes où des mesures explicites doivent être prises pour contrôler l'utilisation des threads. Dans la plupart des cas, le planificateur gérera ces aspects automatiquement.

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