Maison  >  Article  >  développement back-end  >  Décrypter la mise en œuvre des opérations de blocage en langage Go

Décrypter la mise en œuvre des opérations de blocage en langage Go

WBOY
WBOYoriginal
2024-03-23 18:30:05460parcourir

Décrypter la mise en œuvre des opérations de blocage en langage Go

Les opérations de blocage en langage Go sont très courantes, comme la communication entre goroutines, les opérations de canal, etc. L'opération de blocage signifie que le programme arrêtera l'exécution lorsque certaines conditions ne seront pas remplies et ne continuera pas tant que les conditions ne seront pas remplies. Décrypter la mise en œuvre des opérations de blocage dans le langage Go peut nous aider à mieux comprendre le modèle de concurrence et les mécanismes internes du langage Go.

Goroutine et Channel

En langage Go, goroutine est le concept de threads légers, qui peuvent exécuter plusieurs goroutines simultanément dans un programme. Le canal est un pont pour la communication entre les goroutines. Les opérations de transfert de données et de synchronisation entre les goroutines peuvent être réalisées via des canaux.

Ce qui suit est un exemple simple qui montre les opérations de blocage entre les goroutines :

package main

import "fmt"

func task1(ch chan int) {
    fmt.Println("Task 1 is running...")
    ch <- 1 // 往channel发送数据
}

func task2(ch chan int) {
    fmt.Println("Task 2 is running...")
    value := <-ch // 从channel接收数据
    fmt.Println("Received data from Task 1: ", value)
}

func main() {
    ch := make(chan int)
    go task1(ch)
    go task2(ch)

    // 等待所有goroutine执行完毕
    var input string
    fmt.Scanln(&input)
    fmt.Println("Main function exits.")
}

Dans cet exemple, nous avons créé deux goroutines task1 et task2, dans la tâche 1, elles ont envoyé des données au canal et dans la tâche 2, elles ont envoyé des données à partir du canal. En raison des caractéristiques du canal, lorsque le récepteur essaie de lire le canal, s'il n'y a pas de données dans le canal, le récepteur bloquera et attendra l'arrivée des données.

Utilisez select pour implémenter le multiplexage

Dans le langage Go, nous pouvons également utiliser l'instruction select pour implémenter le multiplexage, c'est-à-dire attendre les opérations de plusieurs canaux en même temps. Voici un exemple :

package main

import "fmt"

func task1(ch chan int) {
    for i := 0; i < 5; i++ {
        ch <- i // 往channel发送数据
    }
}

func task2(ch chan int) {
    for i := 0; i < 5; i++ {
        ch <- i // 往channel发送数据
    }
}

func main() {
    ch1 := make(chan int)
    ch2 := make(chan int)

    go task1(ch1)
    go task2(ch2)

    for {
        select {
        case data := <-ch1:
            fmt.Println("Received data from Task 1: ", data)
        case data := <-ch2:
            fmt.Println("Received data from Task 2: ", data)
        }
    }
}

Dans cet exemple, nous avons créé deux goroutines task1 et task2, qui envoient des données à deux canaux respectivement. Utilisez ensuite l'instruction select dans la goroutine principale pour attendre les opérations des deux canaux en même temps. Une fois les données arrivées dans l'un des canaux, la logique de cas correspondante sera exécutée.

Utilisez des canaux tamponnés pour implémenter des opérations non bloquantes

En plus d'utiliser des canaux ordinaires pour les opérations de blocage, nous pouvons également utiliser des canaux tamponnés pour implémenter des opérations non bloquantes. Un canal mis en mémoire tampon peut stocker une certaine quantité de données et l'expéditeur ne sera pas bloqué même si le destinataire n'est pas prêt à recevoir les données. Voici un exemple :

package main

import "fmt"

func main() {
    ch := make(chan int, 2) // 创建一个容量为2的带缓冲的channel

    ch <- 1
    ch <- 2
    // ch <- 3 // 如果再次发送数据,会导致阻塞

    fmt.Println("Sent data to channel.")

    data1 := <-ch
    data2 := <-ch

    fmt.Println("Received data from channel: ", data1, data2)
}

Dans cet exemple, nous créons un canal tamponné d'une capacité de 2 et envoyons d'abord deux données au canal. Même si nous ne recevons pas ces deux données immédiatement, l'opération d'envoi ne bloquera pas. Mais si la troisième donnée est à nouveau envoyée sur ce canal, l'opération d'envoi sera bloquée car le tampon est plein.

Résumé

Grâce aux exemples ci-dessus, nous avons une compréhension approfondie de la mise en œuvre des opérations de blocage dans le langage Go, notamment l'utilisation de canaux pour implémenter des opérations de blocage entre goroutines, l'utilisation de select pour implémenter le multiplexage et l'utilisation de canaux tamponnés pour obtenir un non-blocage. -le blocage fonctionne. Cela revêt une grande importance pour comprendre le modèle de programmation concurrente et le mécanisme interne du langage Go. J'espère que ces exemples pourront aider tout le monde à mieux comprendre et utiliser les fonctionnalités de concurrence du langage Go.

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