Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
November 24, 2022 09:55 am GMT

Handle go routines gracefully

Understanding and handling the Go routines is little bit tricky but once you got to know the cream of Go Routine it will be a cake walk of creating and handling the routines
Updated the code with explanation
please go thru it and please feal free to add comments if i miss anything / you want to add something..!!

package mainimport (    "fmt"    "sync"    "time")const maxRoutines = 5func main() {    HandleUsingWaitGroup()    HandleUsingChannel()}func HandleUsingWaitGroup() {    var wg sync.WaitGroup    // add no of go routines to trigger    wg.Add(maxRoutines)    for i := 1; i <= maxRoutines; i++ {        go waitGroupRoutine(&wg, i)    }    // it will block the main until all go routines run successfully    // whenever wg.Done() informs wait group it will reduce the go routine count by 1    // and it will block until it becomes zero(0)    wg.Wait()}func waitGroupRoutine(wg *sync.WaitGroup, value int) {    // this will inform  wait group once it is done with the task    defer wg.Done()    fmt.Println("i am from waitGroup routine ", value)}// this works with buffered and unbuffered channelsfunc HandleUsingChannel() {    ch := make(chan int, maxRoutines+1)    //uncomment below line if you want to test un-buffered channel    //ch := make(chan int)    // this channel acts as a gatekeeper for the main func    exitCh := make(chan bool)    // this channel acts as a mediator to inform gatekeeper to exit main once all tasks are done    mediatorCh:=make(chan bool)    // trigger go routine and wait for the data in background    go channelRoutine(exitCh,mediatorCh, ch)    for i := 1; i <= maxRoutines; i++ {        // push data to channel        ch <- i        if i == maxRoutines {            // tell mediator to inform exit channel to exit the main func            // and it return the go routine / exit the go routine            mediatorCh <- true            // close the channel here and read residual data in routine            // else we will get a dead lock error because data push to channel is done            // and nothing to read from it and we are trying to access the same...            close(ch)        }    }    // it will block the main until all go routines run successfully    select {    case <-exitCh:        close(exitCh)        fmt.Println("exit from Channel main")        break    }}func channelRoutine(exitCh chan bool,mediatorCh chan bool, ch <-chan int) {    for {        select {        case <-mediatorCh:            // we can read from closed channel            close(mediatorCh)            // read residual data before exiting            // if we use buffered channel size of our data length            //it will have enough space to push data to channel            // once it pushes everything it will exit and routine will close automatically            //and to avoid data miss we have to read channel data before returning            for v := range ch {                // this will show the difference in logs while comparing buffered and un-buffered channels                time.Sleep(time.Second * 1)                fmt.Println(" i am from  channel routine exit state", v)            }            // here we are telling exit channel to exit the main            exitCh<-true            return        case x := <-ch:            fmt.Println(" i am from channel routine", x)        }    }}

Original Link:

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To