Friday, May 3, 2024
HomeGolangClosing a ranged over channel inside employee goroutines - Getting Assist

Closing a ranged over channel inside employee goroutines – Getting Assist


Hello, I’m new to concurrency in go

My query is particularly round these strains of code:

	wg.Wait()
	shut(outcomes)

The goroutines that the wait group are ready on vary over a channel, which can block indefinitely except closed. The shut assertion is occurring after the wait so the channel by no means closes and the employees simply block. In nearly each instance on-line I can discover explaining the idea, the employees know when to cease, as in, its loop conditional will not be a vary.

The pondering for go do(work) is I don’t care how lengthy they take or after they end simply that I get outcomes, some may retry, some take variable time so I’m not utilizing a wait group for them (this might be a mistake and I simply don’t realize it). go do(work) will full faster than it takes to course of the ends in the employee, the extra work, the longer the employees take.

The employees ought to have parallel entry to no matter work is completed, and course of it ultimately. This works with anticipated outcomes after I add a time.Sleep to the blocking a part of the principle operate nevertheless including wg.Wait() ends in a panic. I’m assuming as a result of defer wg.Executed() is rarely decrements, and the employees grasp on attributable to their vary.

Is there a small tweak I could make to my code to make this work or do I’ve to rethink the issue?

I’ve tried numerous different methods to sign that the work being finished is full and that it’s protected to shut the channel utilizing choose and varous movement management statements and helper channels however I can’t fairly appear to get it to work precisely how I’d like. Can anybody steer me in the best course?

package deal essential

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

// some difficult work that takes ~500ms
func do(num int, ch chan<- int) {
	// a number of outcomes are handed to the channel in the actual code
	time.Sleep(time.Length(500 * time.Millisecond))

	/*
		actual work right here is completed to supply a brand new worth to place within the channel
                some occasions producing 2 or 3 values that are added to ch on this name
                I've not correctly illustrated that with num = num*num however quantity comes again
                completely different, and a few occasions a number of entires are added
	*/
        num = num * num
	ch <- num
}

func essential() {

	outcomes := make(chan int)

	// some variety of required difficult work
	for i := 0; i < 53; i++ {
		go do(i, outcomes)
	}

	var wg sync.WaitGroup

	// begin 3 staff which may course of outcomes
	for i := 0; i < 3; i++ {
		wg.Add(1)
		go func(id int) {
			defer wg.Executed()
			employee(id, outcomes)
		}(i)
	}

	// deal with closing the channel when all staff full

        // panic
	wg.Wait()
	shut(outcomes)

	// works
	//time.Sleep(time.Length(10 * time.Second))

	fmt.Println("donezo")
}

// course of the outcomes of do() in a significant approach
func employee(id int, ch <-chan int) {
	fmt.Println("beginning employee", id)

	for i := vary ch {
		fmt.Println("channel val:", i)
	}
}

Hello @b0bu, the speculation says that it’s best to shut the channel within the sender (the “do” operate in your state of affairs).
The shut operate solely sends a message to the channel and your staff will end the vary loop.

Regards!

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments