Work with all values in chan

Hello!
I’m new with Go and don’t understand how work with all unique values in chan at the same time
For example i have unbuffered chan with some objects struct
if i do something like this

func createMessage(d chan SomeStruct) chan MessageStruct{
message:= make(chan MessageStruct)

go func() {
	for v := range d {
			var newM = MessageStruct{}
            newM.ID = v.ID
			message <- newM
		time.Sleep(1 * time.Second)
	}

	close(message )

return message
}

Every 1 second goroutine work only with one object in chan
How current work every 1/2/3/4 second with all objects in chan and write every result in other chan?
Thanks!

Fire goroutines inside the loop.

1 Like

And all routines in loop - merge or just write in one global chan?
How check thet the next routine dosen’t work wih previous value?
Need use waitGroup?

Trying

go func() {
for v := range d {
go func() {
var newM = MessageStruct{}
newM.ID = v.ID
message <- newM
} ()
time.Sleep(1 * time.Second)
}
close(message )
return message
}

and nothing changes((

Yeah, you need a wait group or something. The main issue issue is that you are firing a go routine to handle each of the inputs from the d channel, then you are immediately closing the channel before the go routines have had a chance to finish.

So add each go routine to a wait group and then wait before closing and returning.

Also, do you really intend to return a closed channel at the end?

1 Like

Tell me please how current wait something like this?
func(chan T) chan Done {
c := make(chan Done)
var index int

	go func(){
		for v := range T {
			go func() {
				go func() { 
					index = createNewIndex  //for new ob create new index
				}()
				createNewObj.index = index //set new index new obj
				createNewObj.id = v.id //set new value from chan T
				c <- createNewObj //write new obj in result chan
			}()
		}
	}()
}

close(chan) - because after that function no works with him

in simple example all works current

package main


import (
	//"log"
	"math/rand"
	"time"
	"log"
)

type Phone struct {
	ID int
}

type Message struct {
	ID int
	PhoneID int
	Message string
}

func createChanPhones() chan Phone {
	cp := make(chan Phone)
	go func() {
		for i := 0; i < 100; i++ {
			var nP= Phone{}
			nP.ID = i
			cp <- nP
		}
		close(cp)
	}()

	return cp
}

func main() {

	phones := make(chan Phone)
	phones = createChanPhones()
	//for v := range phones {
	//	log.Println(v)
	//}

	message := make(chan Message)
	message = createM(phones)
	//time.Sleep(2 * time.Second)


	for v := range message {
		log.Println(v)
	}
}

func createM(cp chan Phone) chan Message {
	m := make(chan Message)

	go func() {
		for v := range cp {
			go func() {
				var newM= Message{}
				newM.ID = rand.Intn(1000)
				newM.PhoneID = v.ID
				newM.Message = "some m"
				m <- newM
				time.Sleep(1*time.Second)
				close(m)
			}()
		}
	}()
	return m
}

Even your simple example has problems. You might want to study this a bit:
https://tour.golang.org/concurrency/1

For example:

  • Your channels are not buffered. Thus they will only contain one value until something else reads it to make room for next value
  • The createM() function only fires off a go routine (essentially). Thus the outer one isn’t needed. Just inline the code for v:= range cp...
  • The channels are being closed which makes them unusable to be read from
  • It is unusual to return a channel; typically they are arguments since they are read/write queues. You don’t fill them up and return them for further processing. If that is what you want to do use a slice or a map

At any rate, study the examples on the Go Tour and you’ll see how channels are used.

1 Like

Thanks!

I had a little time this morning… so I tweaked your example. Hope this helps.

https://play.golang.org/p/YXhFAhqbkNr

1 Like

Oops… forgot to close the channels, which cause this error:
fatal error: all goroutines are asleep - deadlock!

fixed: https://play.golang.org/p/J8V7BKH9VXc

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.