Maison  >  Article  >  développement back-end  >  Comment enregistrer simultanément des données dans Golang

Comment enregistrer simultanément des données dans Golang

王林
王林original
2023-05-12 20:50:06508parcourir

Le langage Go est un langage conçu autour de la programmation simultanée. Il possède des threads légers (c'est-à-dire des goroutines) et un mécanisme de communication extensible, ce qui le rend très efficace lors du traitement de données simultanées. Cet article explique comment utiliser les goroutines et les canaux pour implémenter le traitement simultané des données dans Go.

Une goroutine est un thread léger géré par le système d'exécution de Go. Contrairement au modèle de thread traditionnel, les goroutines sont créées et détruites très rapidement et permettent aux développeurs d'exécuter des milliers de goroutines en même temps, ce qui rend Go très adapté au traitement simultané de données.

Pour créer une goroutine, nous pouvons utiliser le mot-clé go, par exemple : go,例如:

go func() {
    // goroutine的执行代码
}()

使用关键字go时,我们将在新的goroutine中执行一个匿名函数。这个函数可以访问当前作用域的变量,因此在编写异步代码时非常方便。

实际上,使用goroutine处理并发数据的过程与使用普通函数处理数据的过程类似。例如,假设我们有一个包含100个元素的int类型的切片,我们想对其所有元素加1并计算它们的总和,我们可以这样写:

func main() {
    nums := []int{1, 2, 3, ..., 100}
    sum := 0
    for _, num := range nums {
        go func(n int) {
            sum += n + 1
        }(num)
    }
    time.Sleep(time.Second) // 等待所有goroutine完成
    fmt.Println(sum) // 输出10100
}

在上面的代码中,我们将每个元素启动一个goroutine,并在其中将其加1,然后将结果相加以计算总和。需要注意的是,由于goroutine是异步执行的,因此我们需要使用time.Sleep来等待所有goroutine完成。

在方法内部调用goroutine会在调用堆栈上创建一个新的goroutine,这些goroutine与原始goroutine共享堆和栈,并且可以访问相同的变量。这种并发方式允许我们高效地并发处理数据。但是,需要注意的是,由于共享变量可能会导致数据竞态,因此我们必须确保对共享变量的并发访问是同步的。

为了解决这个问题,Go提供了通道。通道是一种同步机制,它允许goroutine之间安全地发送和接收数据。我们可以使用make函数来创建一个通道,例如:

ch := make(chan int)

这将创建一个带有int类型的通道,我们可以在它的缓存中放置一些值,或发送和接收值。

发送数据到通道使用<-操作符:

ch <- 1 // 将1发送到通道

接收数据可以使用<-操作符,例如:

x := <-ch // 从通道中接收一个值,并将其赋值给x

通道操作是阻塞的,这意味着如果我们尝试从空通道中接收数据,程序将被阻塞,直到有能够发送的数据。同样,如果我们尝试向已满的通道发送数据,程序也会被阻塞,直到有其他goroutine可以接收数据。

我们可以使用通道来同步goroutine之间的数据。例如,假设我们有一个通道,每次从通道中接收两个数字,并将它们相加。这就是一个简单的示例:

func sum(ch chan int, nums ...int) {
    for _, n := range nums {
        ch <- n
    }
    close(ch)
}

func main() {
    ch := make(chan int)
    go sum(ch, 1, 2, 3, 4, 5) // 将1,2,3,4,5发送到通道ch中

    sum := 0
    for n := range ch {
        sum += n
    }
    fmt.Println(sum) // 输出15
}

在上面的示例中,我们首先创建一个通道ch,并启动了一个sumrrreee

Lorsque nous utilisons le mot-clé go, nous exécuterons une fonction anonyme dans la nouvelle goroutine . Cette fonction peut accéder aux variables dans la portée actuelle, elle est donc très pratique lors de l'écriture de code asynchrone.

En fait, le processus d'utilisation de goroutine pour traiter des données simultanées est similaire au processus d'utilisation de fonctions ordinaires pour traiter des données. Par exemple, disons que nous avons une tranche de type int contenant 100 éléments et que nous voulons ajouter 1 à tous ses éléments et calculer leur somme, nous pouvons écrire comme ceci :

rrreee

Dans le code ci-dessus, on démarre chaque élément Une goroutine et ajoutez-y 1 et additionnez les résultats pour calculer la somme. Il convient de noter que puisque les goroutines sont exécutées de manière asynchrone, nous devons utiliser time.Sleep pour attendre que toutes les goroutines se terminent. 🎜🎜L'appel d'une goroutine à l'intérieur d'une méthode crée une nouvelle goroutine sur la pile d'appels qui partage le tas et la pile avec la goroutine d'origine et a accès aux mêmes variables. Cette approche de concurrence nous permet de traiter efficacement les données simultanément. Cependant, il est important de noter que, puisque les variables partagées peuvent provoquer des courses de données, nous devons nous assurer que les accès simultanés aux variables partagées sont synchronisés. 🎜🎜Pour résoudre ce problème, Go propose des chaînes. Les canaux sont un mécanisme de synchronisation qui permet aux goroutines d'envoyer et de recevoir des données en toute sécurité entre les goroutines. On peut utiliser la fonction make pour créer un canal, par exemple : 🎜rrreee🎜 Cela créera un canal avec un type int et nous pourrons mettre des valeurs dans son cache, ou envoyer et recevoir des valeurs . 🎜🎜Pour envoyer des données au canal, utilisez l'opérateur <- : 🎜rrreee🎜Pour recevoir des données, vous pouvez utiliser l'opérateur <-, par exemple : 🎜 rrreee🎜Le fonctionnement du canal est bloquant, ce qui signifie que si nous essayons de recevoir des données d'un canal vide, le programme sera bloqué jusqu'à ce qu'il y ait des données pouvant être envoyées. De même, si nous essayons d'envoyer des données à un canal plein, le programme sera bloqué jusqu'à ce qu'un autre goroutine puisse recevoir les données. 🎜🎜Nous pouvons utiliser des canaux pour synchroniser les données entre les goroutines. Par exemple, disons que nous avons une chaîne qui reçoit à chaque fois deux nombres de la chaîne et les additionne. Ceci est un exemple simple : 🎜rrreee🎜Dans l'exemple ci-dessus, nous créons d'abord un canal ch et démarrons une goroutine de la fonction sum, qui reçoit n'importe quel nombre et l'envoie au canal. Ensuite, dans la fonction principale, nous utilisons une simple boucle for pour lire les données des canaux et les additionner. 🎜🎜Il convient de noter que les opérations des chaînes sont bloquantes, alors portez une attention particulière aux problèmes de blocage lors de l'utilisation des chaînes. Si nous envoyons des données à un canal qui a été fermé avant de lire les données, ou si nous lisons des données à partir d'un canal déjà vide, le programme se bloquera et ne se terminera jamais. 🎜🎜En bref, le modèle de concurrence du langage Go est très adapté au traitement de données simultanées, et un traitement simultané efficace peut être facilement réalisé à l'aide de goroutines et de canaux. Cependant, lorsque vous utilisez le modèle de concurrence, vous devez être particulièrement attentif aux courses de données et aux blocages pour garantir l'exactitude et l'efficacité du programme. 🎜

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