Table des matières
Contenu de la question
解决方法
Maison développement back-end Golang Comprendre le comportement du canal de blocage Golang en écrivant plusieurs fois sur le canal

Comprendre le comportement du canal de blocage Golang en écrivant plusieurs fois sur le canal

Feb 09, 2024 pm 02:27 PM
golang开发

通过对通道进行多次写入来理解 golang 阻塞通道行为

Dans cet article, l'éditeur PHP Youzi vous présentera comment comprendre le comportement de Golang consistant à bloquer le canal en écrivant plusieurs fois sur le canal. Dans Golang, les canaux sont un mécanisme important pour transmettre des données entre coroutines. Lorsqu'un canal est plein, les opérations d'écriture sont bloquées jusqu'à ce que le canal soit libre. Nous démontrerons ce comportement avec un exemple simple et expliquerons comment fonctionnent les canaux de blocage et comment les utiliser. Que vous soyez un développeur Golang débutant ou expérimenté, vous pouvez acquérir des connaissances utiles et une expérience pratique grâce à cet article. commençons!

Contenu de la question

Je suis nouveau sur Golang et j'essaie de comprendre la concurrence dans le langage. J'ai un code qui pousse certaines valeurs vers un canal puis les lit.

package main

import (
    "log"
    "time"
)

func Greet2(c chan string) {
    // logging to Stdout is not an atomic operation
    // so artificially, sleep for some time
    time.Sleep(2 * time.Second)
    
    // 5. until below line reads and unblock the channel
    log.Printf("5. Read Greet2:: %s\n\n", <-c)
}

func Greet(c chan string) {
    // 4. Push a new value to the channel, this will block
    // Process will look for other go routines to execute
    log.Printf("4. Add 'Greet::John' to the channel, block until it is read. Remember, 'Greet' goroutine will block and only other goroutines can run even though this go routine can pull the value out from the channel.\n\n")
    c <- "Greet::John!"
    
    // 8. This statement will never execute
    log.Printf("8. Read Greet:: %s !\n\n", <-c)
}

func main() {

    c := make(chan string)

    log.Println("1. Main start")
    
    // 2. Both go routine will be declared and both will
    // for a value to be inserted in the channel
    log.Println("2. Declare go routines.\n\n")
    go Greet(c)
    go Greet2(c)
    
    // 3. write will block
    log.Println("3. Add 'main::Hello' to the channel, block until it is read. Remember, 'main' goroutine will block and only other goroutines can run even though this go routine can pull the value out from the channel.\n\n")
    c <- "main::Hello"
    
    // Sleep to give time goroutines to execute
    time.Sleep(time.Second)
    
    // 6. read the channel value.
    log.Printf("6. Read main:: %s \n\n", <-c)
    
    // 7. Insert a new value to the channel
    log.Println("7. Add 'main::Bye' to the channel, block until it is read.\n")
    c <- "main::Bye"
    
    // Sleep to give time goroutines to execute
    time.Sleep(time.Second)
    log.Println("9. Main stop")

}
Copier après la connexion

Le résultat du programme ci-dessus est

2023/09/02 21:58:07 1. Main start
2023/09/02 21:58:07 2. Declare go routines.


2023/09/02 21:58:07 3. Add 'main::Hello' to the channel, block until it is read. Remember, 'main' goroutine will block and only other goroutines can run even though this go routine can pull the value out from the channel.


2023/09/02 21:58:07 4. Add 'Greet::John' to the channel, block until it is read. Remember, 'Greet' goroutine will block and only other goroutines can run even though this go routine can pull the value out from the channel.

2023/09/02 21:58:10 5. Read Greet2:: main::Hello

2023/09/02 21:58:11 6. Read main:: Greet::John!

2023/09/02 21:58:11 7. Add 'main::Bye' to the channel, block until it is read.

2023/09/02 21:58:11 8. Read Greet:: main::Bye !

2023/09/02 21:58:12 9. Main stop
Copier après la connexion

Je ne comprends pas pourquoi 4.(另一个写入通道)在 5.(第一次从通道读取)之前执行,因为 3. 将阻塞,并且在读取值之前通道不可用来自它(在步骤 5. 中)。我是否误解了阻塞行为,在步骤 3. 中,只有 main goroutine 块和 Greet (在步骤 4. ) peut écrire une valeur supplémentaire sur la chaîne ? Une explication dissiperait vraiment ma confusion :)

Bravo, D.D.

<小时/>

Merci pour votre réponse, j'ai créé un programme plus simple à démontrer. Concurrence

package main

import (
        "fmt"
)

func do2(c chan int) {
        fmt.Println(<-c)
}

func do(c chan int) {
        // 4. this statement is trying to write another value "2" to the channel
        // Channel already contains "1" as the value which has not been read yet.
        // this statement will wait for "1" to get read and block the execution.
        // Scheduler will look for other goroutines that can execute.
        // However, this("do") is blocked as well as "main" is blocked too and
        // there are no other goroutines to execute.
        // Hence, will result in a "Deadlock" fatal error.
        c <- 2
        fmt.Println(<-c)
}

func main() {

        // 1. Declare a channel
        c := make(chan int)
        // 2. Declare "do" goroutine
        go do(c)
        // 3. write "1" to the channel
        // This will block and wait for program's other goroutines to read the value.
        // however, there is only "do" goroutine is defined can run at this point.
        // Scheduler, will try to run "do" goroutine.
        c <- 1
        go do2(c)

}
Copier après la connexion

Deadlock peut être résolu en échangeant les instructions c <- 1 et go do2(c). 死锁可以通过交换c <- 1go do2(c)语句来修复。

解决方法

在 Go 中,当您在通道上发送值时(步骤 3 中的 c <- "main::Hello"),发送 Goroutine 将阻塞,直到有另一个 Goroutine 准备好从通道接收值。然而,这并不意味着没有其他 goroutine 可以继续执行。在您的代码中, GreetGreet2

Solution

Dans Go, lorsque vous envoyez une valeur sur un canal (c <- "main::Hello" à l'étape 3), la Goroutine d'envoi se bloquera jusqu'à ce qu'il y ait une autre Goroutine A. prêt à recevoir les valeurs du canal. Cependant, cela ne signifie pas qu’aucune autre goroutine ne peut continuer à s’exécuter. Dans votre code, les
    coroutines attendent toutes une valeur du canal, donc lorsque vous envoyez la valeur à l'étape 3, l'une d'elles (aucune garantie laquelle) se débloquera et poursuivra l'exécution.
  1. cPermettez-moi de détailler la séquence des événements étape par étape :
  2. GreetGreet2Le programme principal démarre et vous créez une chaîne
  3. .
  4. GreetGreet2Vous avez déclaré deux goroutines,
  5. , et toutes deux attendent une valeur du canal.
  6. Greet 解除阻塞并继续执行。它记录消息“4. 将‘Greet::John’添加到频道...”并发送“Greet::John!”在频道上。这会再次阻塞 GreetVous envoyez une valeur "main::Hello" sur le canal, qui bloque la goroutine principale jusqu'à ce que d'autres goroutines lisent les données du canal. Cependant, l'un des deux Goroutines (
  7. ) ne sera pas empêché de recevoir la valeur.
  8. Greet2
  9. , car aucun autre goroutine ne peut lire la chaîne pour le moment.
  10. Débloquez et poursuivez l'exécution. Il enregistre le message "5. Read Greet2::main::Hello" et lit la valeur "main::Hello" du canal. Greet 在向通道写入时仍被阻止,而 Greet2
  11. Main se déverrouille, enregistre "6. Lisez main::Greet::John!" et lit "Greeting::John depuis la chaîne".
  12. GreetMain envoie une autre valeur "main::Bye" sur le canal. À ce stade,
  13. est toujours bloqué lors de l'écriture sur la chaîne, et
  14. ne peut pas lire sur la chaîne.
Puisque

est toujours bloqué en écriture, il n'enregistre jamais "8. Read Greet:: main::Bye Greet2 碰巧首先被解锁,但也可能是 Greet !"

Site principal.

🎜La clé pour comprendre le comportement ici est que lorsque vous envoyez une valeur sur un canal, cela déverrouille toutes les goroutines qui attendent de lire les données du canal. L'ordre dans lequel les goroutines en attente sont débloquées n'est pas défini et dépend du planificateur. Dans votre cas, 🎜 se trouve être déverrouillé en premier, mais cela pourrait aussi l'être 🎜. 🎜 🎜En résumé, le comportement que vous observez est tout à fait cohérent avec le fonctionnement des canaux Go, avec la nuance que l'ordre d'exécution entre Goroutines concurrents n'est pas garanti. 🎜

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 de ce site Web
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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Développez des applications de bureau puissantes à l'aide de Golang Développez des applications de bureau puissantes à l'aide de Golang Mar 19, 2024 pm 05:45 PM

Utilisez Golang pour développer des applications de bureau puissantes. Avec le développement continu d'Internet, les utilisateurs sont devenus indissociables de différents types d'applications de bureau. Pour les développeurs, il est crucial d’utiliser des langages de programmation efficaces pour développer des applications bureautiques puissantes. Cet article explique comment utiliser Golang (langage Go) pour développer des applications de bureau puissantes et fournit des exemples de code spécifiques. Golang est un langage de programmation open source développé par Google. Il présente les caractéristiques de simplicité, d'efficacité, de forte concurrence, etc., et convient parfaitement.

Défis de sécurité dans le développement de Golang : Comment éviter d'être exploité pour la création de virus ? Défis de sécurité dans le développement de Golang : Comment éviter d'être exploité pour la création de virus ? Mar 19, 2024 pm 12:39 PM

Défis de sécurité dans le développement de Golang : Comment éviter d'être exploité pour la création de virus ? Avec la large application de Golang dans le domaine de la programmation, de plus en plus de développeurs choisissent d'utiliser Golang pour développer différents types d'applications. Cependant, comme pour d’autres langages de programmation, le développement de Golang présente des problèmes de sécurité. En particulier, la puissance et la flexibilité de Golang en font également un outil potentiel de création de virus. Cet article abordera les problèmes de sécurité dans le développement de Golang et fournira quelques méthodes pour éviter G.

Étapes et conseils pour programmer avec Golang sur Mac Étapes et conseils pour programmer avec Golang sur Mac Mar 03, 2024 am 08:30 AM

Titre : Étapes et techniques d'utilisation de la programmation Golang sur Mac Dans le domaine actuel du développement logiciel, Golang (également connu sous le nom de Go), en tant que langage de programmation efficace, concis et hautement simultané, a attiré l'attention de plus en plus de développeurs. . Lors de la programmation de Golang sur la plate-forme Mac, vous pouvez utiliser certains outils et techniques pour améliorer l'efficacité du développement. Cet article présentera les étapes et les techniques d'utilisation de la programmation Golang sur Mac et fournira des exemples de code spécifiques pour aider les lecteurs à mieux comprendre et appliquer. Étape 1 : Installer Gol

Recherche sur l'impact et le rôle de Golang sur le développement de la blockchain Recherche sur l'impact et le rôle de Golang sur le développement de la blockchain Feb 26, 2024 pm 04:24 PM

Golang (langage Go en abrégé) en tant que langage de programmation a progressivement émergé dans le domaine de la blockchain ces dernières années. Ses capacités de traitement simultané efficaces et ses fonctionnalités de syntaxe concises en font un choix privilégié dans le développement de la blockchain. Cet article explorera comment Golang aide au développement de la blockchain et démontrera sa supériorité dans les applications blockchain à travers des exemples de code spécifiques. 1. Avantages de Golang dans le domaine de la blockchain : Capacités de traitement simultanées efficaces : les nœuds du système blockchain doivent traiter une grande quantité de transactions et de données en même temps, et Gola

Quels langages de programmation sont couramment utilisés par les développeurs Golang ? Quels langages de programmation sont couramment utilisés par les développeurs Golang ? Mar 18, 2024 pm 09:06 PM

Golang est un langage de programmation open source développé par Google et est largement utilisé dans le développement de services back-end, le cloud computing, la programmation réseau et d'autres domaines. En tant que langage typé statiquement, Golang dispose d'un modèle de concurrence efficace et d'une puissante bibliothèque standard, il est donc privilégié par les développeurs. Cependant, dans le développement réel, les développeurs Golang doivent généralement combiner d'autres langages de programmation pour le développement de projets afin de répondre aux besoins de différents scénarios. PythonPython est un langage de programmation orienté objet concis, clair et facile à apprendre.

Le framework Go Kit aide à améliorer les performances de l'API Golang Le framework Go Kit aide à améliorer les performances de l'API Golang May 07, 2024 pm 03:24 PM

Gokit est un framework de microservices Golang qui améliore les performances des API grâce à des fonctionnalités optimisées, évolutives, maintenables et conviviales pour les tests. Il fournit une gamme d'outils et de modèles qui permettent aux utilisateurs de créer rapidement des API performantes et maintenables. En production réelle, il est largement utilisé dans la construction d’API de grandes plateformes telles que Netflix, Spotify et Uber, traitant des requêtes massives.

Avantages et inconvénients de l'utilisation de Golang pour développer des jeux mobiles Avantages et inconvénients de l'utilisation de Golang pour développer des jeux mobiles Mar 05, 2024 pm 03:51 PM

Avantages et inconvénients de l'utilisation de Golang pour développer des jeux mobiles Avec la popularité des appareils mobiles et l'amélioration continue de leurs performances, le marché des jeux mobiles devient de plus en plus populaire, attirant de plus en plus de développeurs à le rejoindre. Lors du choix d'un langage de développement, Golang, en tant que langage rapide, efficace et facile à apprendre, attire l'attention de nombreux développeurs. Cet article discutera des avantages et des inconvénients de l'utilisation de Golang pour développer des jeux mobiles et l'illustrera à travers des exemples de code spécifiques. Avantages : Forte multiplateforme : Golang peut être compilé en binaires pour différentes plates-formes

L'approche de Golang pour la mise en œuvre d'applications de bureau multiplateformes L'approche de Golang pour la mise en œuvre d'applications de bureau multiplateformes Mar 20, 2024 am 11:39 AM

Golang (également connu sous le nom de langage Go) est un langage de programmation open source développé par Google. Il est de plus en plus populaire parmi les développeurs grâce à sa simplicité, son efficacité et ses fonctionnalités puissantes. Lors de la mise en œuvre d'applications de bureau multiplateformes, Golang fournit également des outils et bibliothèques puissants pour rendre le développement plus facile et plus efficace. Cet article explique comment utiliser Golang pour implémenter des applications de bureau multiplateformes et fournit des exemples de code spécifiques à titre de référence. 1. Utilisez la bibliothèque fyne pour créer des applications GUI multiplateformes dans Golang, une

See all articles