Maison  >  Article  >  développement back-end  >  Types et règles de canaux dans la programmation concurrente des fonctions Golang

Types et règles de canaux dans la programmation concurrente des fonctions Golang

王林
王林original
2024-04-18 08:57:02290parcourir

Channel est un mécanisme de communication dans le langage Go permettant de transférer en toute sécurité des données entre des fonctions concurrentes. Il offre une protection contre la course aux données pour éviter l'accès direct à la mémoire partagée. Les types de canaux incluent les canaux sans tampon (chan T) et les canaux avec tampon (chan T, int). Les règles incluent l'envoi d'une valeur (

Types et règles de canaux dans la programmation concurrente des fonctions Golang

Types de canaux et règles dans la programmation simultanée des fonctions du langage Go

Les canaux sont un mécanisme de communication dans le langage Go permettant de transférer en toute sécurité des données entre des fonctions concurrentes. Ils fournissent une couche d'abstraction qui élimine le besoin pour les fonctions d'accéder directement à la mémoire partagée, évitant ainsi les courses aux données.

Types de canaux

  • Canal sans tampon (chan T) : Ce type de canal n'a pas de tampon interne, donc l'expéditeur et le destinataire doivent être prêts en même temps à communiquer.
  • Canal tamponné (chan T, int) : Ce type de canal possède un tampon interne d'une taille spécifiée pour stocker les valeurs. Il permet à l'expéditeur d'envoyer une valeur lorsque le destinataire n'est pas prêt à la recevoir, et vice versa.

Règles de chaîne

  • Envoyer une valeur : Utilisez l'opérateur envoyer () pour envoyer une valeur à une chaîne. Le canal doit être verrouillé à l'aide de <code> avant d'envoyer une valeur. <code>send 操作符 () 将值发送到通道。必须先使用 <code> 锁定通道,然后再发送值。
  • 接收值:使用 receive 操作符 (->) 从通道接收值。与发送值类似,必须先使用 chan 锁定通道,然后再接收值。
  • 关闭通道:使用 close(chan) 关闭通道。关闭后,无法再向通道发送值,但可以继续接收已发送的值。
  • 通道容量:缓冲通道有一个指定的最大容量,由创建时指定的第二个参数确定。如果通道已满,发送方将阻塞,直到有空间可用。
  • 选择:select 语句允许从多个通道进行选择性接收或发送。它提供了事件驱动的并发编程模型。

实战案例

考虑一个计算素数的程序:

package main

import (
    "fmt"
    "math"
    "sync"
    "time"
)

// 工作单元
type WorkUnit struct {
    n        uint64
    isPrime  bool
    finished chan bool
}

// 素数计算函数
func isPrime(n uint64) bool {
    if n <= 1 {
        return false
    }
    for i := uint64(2); i <= uint64(math.Sqrt(float64(n))); i++ {
        if n%i == 0 {
            return false
        }
    }
    return true
}

// 工作器函数
func worker(in, out chan *WorkUnit, wg *sync.WaitGroup) {
    defer wg.Done()
    for unit := range in {
        unit.isPrime = isPrime(unit.n)
        close(unit.finished)
        out <- unit
    }
}

func main() {
    // 输入通道
    in := make(chan *WorkUnit)
    // 输出通道
    out := make(chan *WorkUnit)

    // 初始化工作单元
    units := make([]*WorkUnit, 500000)
    for i := range units {
        units[i] = &WorkUnit{
            n:        uint64(i),
            finished: make(chan bool),
        }
    }

    // 启动工作器
    wg := &sync.WaitGroup{}
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go worker(in, out, wg)
    }

    // 将工作单元推送到输入通道
    start := time.Now()
    for _, unit := range units {
        in <- unit
    }
    close(in)

    // 从输出通道接收结果
    for unit := range out {
        <-unit.finished
    }
    elapsed := time.Since(start)

    fmt.Printf("Took %s\n", elapsed)
}

在这个示例中:

  • in 通道是无缓冲通道,用于将工作单元发送到工作器函数。
  • out 通道是缓冲通道,用于将计算结果传回主函数。
  • finished
Recevoir une valeur :

Utilisez l'opérateur receive (->) pour recevoir une valeur d'un canal. Semblable à l'envoi de valeurs, le canal doit être verrouillé à l'aide de chan avant de recevoir des valeurs.

🎜🎜Fermer la chaîne : 🎜Utilisez close(chan) pour fermer la chaîne. Après la fermeture, plus aucune valeur ne peut être envoyée au canal, mais les valeurs déjà envoyées peuvent continuer à être reçues. 🎜🎜🎜Capacité des canaux : 🎜Les canaux tampons ont une capacité maximale spécifiée, déterminée par le deuxième paramètre spécifié lors de la création. Si le canal est plein, l'expéditeur bloque jusqu'à ce que de l'espace soit disponible. 🎜🎜🎜Select : L'instruction 🎜select permet la réception ou l'envoi sélectif à partir de plusieurs canaux. Il fournit un modèle de programmation simultanée piloté par les événements. 🎜🎜🎜🎜Exemple pratique🎜🎜🎜Considérons un programme qui calcule des nombres premiers : 🎜rrreee🎜Dans cet exemple : 🎜🎜🎜Le canal in est un canal sans tampon utilisé pour envoyer des unités de travail à la fonction des travailleurs. 🎜🎜Le canal out est un canal tampon utilisé pour transférer les résultats des calculs vers la fonction principale. 🎜🎜Le canal terminé est un canal non tamponné utilisé pour signaler la fonction principale une fois que la fonction de travail a terminé son calcul. 🎜🎜🎜Ce programme montre comment utiliser les canaux pour implémenter des calculs simultanés dans Go, en utilisant efficacement plusieurs cœurs de processeur. 🎜

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