• about reply
Alpha Reply Logo
Menu
  • Lösungen
    Lösungen
    • Lösungen
    • Fusion
    • Synapse
  • Insights
    Insights
    • Insights
    • Erfolgreiche Projekte
    • Artikel
    • Events
    • Tutorials
  • Partnerschaften
Choose language:
  • about Reply
Alpha Reply Logo
Focus On

Go Concurrency mit WaitGroup

goconcurrencywithwaitgroup-1408x704.jpg 0

Welcome back to the series tutorials on Go Concurrency. If you missed the previous tutorials please refer to: Go Concurrency with GoRoutines.

In this tutorial, we will help you to understand the concept of WaitGroup.

What is WaitGroup

In some scenarios, you may need to block certain parts of code to allow these GoRoutines to complete their execution according to your needs. A common usage of WaitGroup is to block the main function because we know that the main function itself is also a GoRoutine.

      package main
 
import (
    "fmt"
    "sync"
)
 
func main() {
 
    wg := sync.WaitGroup{}
    wg.Add(1)
 
    go print(&wg)
 
    wg.Wait()
 
    fmt.Println("hello from main")
}
 
func print(wg *sync.WaitGroup) {
    fmt.Println("hello from goroutine")
    wg.Done()
}

You need to import the sync package before you can use WaitGroup. WaitGroup is of struct type and it has three functions, which you can use: Add(int), Wait() and Done(). The mechanics of the WaitGroup is that it has a counter that starts at zero. Whenever you call Add(int), you are increasing the counter by the parameter specified in the Add(int) function.

On the other hand, each Done() function decreases the counter by 1. The WaitGroup panics if the counter is less than 0 and therefore, you need to make sure Done() is not called more than you need to. Moreover, if you use Done() before Add(), it will also cause a panic. The Wait() function blocks the code and it will be released until the counter is zero.

In the example, we first declare a variable wg and instantiate a new sync.WaitGroup{}. We call Add(1) before attempting to execute our go print(). We then pass the pointer to wg in print() so that we can use Done() function once the print task is completed. We call wg.Wait() to block the main GoRoutine and it will release the block until the go print() is done.

Can you spot the problem?

A little exercise for the reader, the following code produces deadlock. Do you know why?

      package main
import (
    "fmt"
    "sync"
)
 
func main() {
 
    wg := sync.WaitGroup{}
    wg.Add(2)
 
    go printCat(&wg)
    wg.Wait()
 
    go printDog(&wg)
    wg.Wait()
 
    fmt.Println("hello from main")
}
 
func printCat(wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        fmt.Println("Cat")
    }
    wg.Done()
}
 
func printDog(wg *sync.WaitGroup){
    for i := 0; i < 5; i++ {
        fmt.Println("Dog")
    }
    wg.Done()
}
 

This is because the main GoRoutine has been blocked forever by the first wg.Wait(). We increase the counter of wg by 2 by using wg.Add(2). After the printCat() GoRoutine finishes, the counter remains 1 and blocks the main GoRoutine forever.

Multiple GoRoutines with WaitGroup

Let's have a look at another example to illustrate the power of using GoRoutines to multithread for loop in Go if each iteration is independent to one another.

      package main

import (
   "fmt"
   "sync"
)

func main() {

   wg := sync.WaitGroup{}
   for i:=0; i<10; i++{
      wg.Add(1)
      go dosomething(&wg)

   }

   wg.Wait()
   fmt.Println("Finish for loop")
}

func dosomething(wg *sync.WaitGroup) {
   fmt.Println("Do something")
   wg.Done()
}

We spawn one GoRoutine at each iteration of the for loop and each GoRoutine will perform a task which is independent to the other tasks. The benefit of using GoRoutines here is that the next iteration does not need to wait for the previous task to finish. We are using WaitGroups to finish the execution of all tasks within the for loop before we execute fmt.Println("Finish for loop").

So far, all GoRoutines have no communication between them. In the next tutorial, we will introduce the concept of Channels which make data sharing between GoRoutines possible.

Stay tuned!

RELATED CONTENTS

Alpha Reply & yes®

Mit dem Beginn des neuen Jahres freuen wir uns bekannt geben zu können, dass Alpha Reply und yes.com erfolgreich eine strategische Partnerschaft geschlossen haben.

Go Concurrency mit Channels

In diesem Tutorial hilft Alpha Reply dabei, das Konzept der Kanäle zu verstehen. Während einer Concurrency-Programmierung spielt die Kommunikation in einer gemeinsam genutzten Speicherumgebung eine wichtige Rolle in der Synchronisierung des gesamten Programms. In Go ist Channels eine integrierte Funktion für Synchronisationen.

Go Concurrency mit Channels 0
Go concurrency mit Mutex 0

Go concurrency mit Mutex

Mutex ist eines der kritischsten Konzepte der Concurrency-Programmierung. Wenn GoRoutine und Channels für die parallele Programmierung verwendet werden, was passiert, wenn zwei GoRoutines versuchen, auf denselben Datenteil an derselben Speicherstelle zuzugreifen? ...

 
 
 
 
Reply ©​​ 2023​ - ​​​​Datenschutz​​​ - Impressum
Cookie-Einstellungen​
  • Über Reply
  • Investoren​​
  • Newsroom
  • Folgen Sie uns auf​​​​​​​​


  • ​​
  • ​
​
  • ​​​​Company Information
  • ​​​​Datenschutz- und Cookie Richtlinie
  • Datenschutzhinweis (Kunden)
  • Datenschutzhinweis (Dienstleister)
  • Datenschutzhinweis (Bewerber)
​Reply Enterprise Social Network​