Maison  >  Article  >  développement back-end  >  L'écriture sur « stdout » dans Go est-elle vraiment Thread-Safe ?

L'écriture sur « stdout » dans Go est-elle vraiment Thread-Safe ?

Susan Sarandon
Susan Sarandonoriginal
2024-10-27 07:10:02412parcourir

 Is Writing to `stdout` in Go Truly Thread-Safe?

L'écriture simultanée sur la sortie standard est-elle Threadsafe ?

Cette question concerne la sécurité des threads des écritures simultanées sur le flux de sortie standard (stdout) dans Aller. Plus précisément, considérons le code suivant :

<code class="go">package main

import (
    "fmt"
    "os"
    "strings"
)

func main() {
    x := strings.Repeat(" ", 1024)
    go func() {
        for {
            fmt.Fprintf(os.Stdout, x+"aa\n")
        }
    }()

    go func() {
        for {
            fmt.Fprintf(os.Stdout, x+"bb\n")
        }
    }()

    go func() {
        for {
            fmt.Fprintf(os.Stdout, x+"cc\n")
        }
    }()

    go func() {
        for {
            fmt.Fprintf(os.Stdout, x+"dd\n")
        }
    }()

    <-make(chan bool)
}</code>

Malgré l'absence de toute course apparente aux données, il y a eu un débat concernant la sécurité des threads de ce code. Pour clarifier ce problème, examinons les mécanismes d'écriture sur stdout et examinons les recommandations et les références.

Package FMT et IO.Writer

Les fonctions du package fmt, tel que fmt.Fprintf, acceptez un argument implémentant l'interface io.Writer. Ils appellent en interne la méthode Write de cette interface.

OS et accès simultané à stdout

os.Stdout est une implémentation de l'interface io.Writer qui dirige la sortie vers la sortie standard du système. Lorsque plusieurs goroutines écrivent simultanément sur os.Stdout, la sémantique réelle de cette opération est déléguée au système d'exploitation sous-jacent.

Dans le cas des systèmes POSIX, l'appel système write(2) est utilisé. POSIX spécifie que les appels write(2) simultanés sont atomiques pour les fichiers normaux et les liens symboliques. Cependant, cette garantie ne s'étend pas aux autres types de fichiers ni aux systèmes non-POSIX.

Bibliothèque et wrappers standard Go

La bibliothèque standard Go fournit des wrappers pour l'écriture dans descripteurs de fichiers et sockets. Ces wrappers implémentent l'interface io.Writer et, dans le cas de os.Stdout, redirigent les opérations vers l'appel système concerné.

Le runtime Go garantit que ces wrappers sont sécurisés en interne pour un accès simultané. Cependant, ils relaient simplement les écritures vers le système d'exploitation sous-jacent, de sorte que la sémantique de concurrence est finalement déterminée par le système d'exploitation.

Implications pour les écritures simultanées sur stdout

  • Les appels simultanés à fmt.Fprintf écrivant sur os.Stdout peuvent être utilisés en toute sécurité dans le runtime Go.
  • L'ordre réel de la sortie peut être non déterministe et dépend de facteurs tels que le système d'exploitation, le runtime Go, et la charge du système.

Recommandations

  • Si l'ordre de sortie des écritures simultanées sur la sortie standard est critique, envisagez d'utiliser des mécanismes de synchronisation pour appliquer un ordering.
  • Le package de journalisation fournit un cadre de journalisation qui inclut une journalisation thread-safe vers la sortie standard (ou d'autres destinations) avec des horodatages et des en-têtes de journal contrôlables.

Références

  • Appel système POSIX write(2) : https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html
  • Interface io.Writer dans Go : https://pkg.go.dev/io#Writer
  • Package Fmt dans Go : https://pkg.go.dev/fmt
  • Package de journaux dans Go : https:// pkg.go.dev/log

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