An Interest In:
Web News this Week
- April 24, 2024
- April 23, 2024
- April 22, 2024
- April 21, 2024
- April 20, 2024
- April 19, 2024
- April 18, 2024
November 24, 2022 09:55 am GMT
Original Link: https://dev.to/saiteja/handle-go-routines-gracefully-279j
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: https://dev.to/saiteja/handle-go-routines-gracefully-279j
Share this article:
Tweet
View Full Article
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To