Using channels in Go created by a 'for' loop

Issue

Can channels created in a for loop be interchangeably used by subroutines running concurrently from that for loop?

Pseudocode is below:

for i := range Map {
      channel := make(chan my_type, buff_size)

      go subroutine(Map[i], channel)
}

func subroutine(name valueType, channel channelType) {
    // Stuff here
}

Is there a way were subroutine(Map[0]) for example, could access another channel created during another iteration of the for loop, i.e., channel of subroutine(Map[1])?


Context: I’m currently working on a project where I have to simulate different populations of cells. Each cell has the ability to divide, differentiate, etc. To replicate the real system, the different populations have to run concurrently with one another. The issue is that I have to insert/remove a cell of a specific population type while working on a different population, this is where the channels come into play. I was thinking of running the populations concurrently each of them having an associated channel. And this is why I’m asking if we can use channels created in different for loop iterations.


Here is some of my code to support my context description with comments explaining the different elements. I’ve included channels, but I have no idea if it works. I’m hoping it helps with understanding what I’m trying to do:

func main() {
  // Where envMap is a map[int]Population and Population is a struct
  envMap := initialiseEnvironment(envSetupInfo)

  // General simulation loop
  for i := 0; i < 10; i++ {
     // Loop to go through all envMap elements in parallel
     for eachKey := range envMap {
         channel := make(chan type)
         go simulateEnv(envMap[eachKey])
     }
  }
}

func simulateEnv(cellPopulation Population, channel chan) {
  // Each Population has a map[int]Cell where Cell is a struct with cell properties
  cellMap := cellPopulation.cellMap

  for eachCell := range cellMap {
      go divisionTransition(eachCell, channel)
  }
}

Solution

Assuming each element of the map is a struct, you could make a field to hold references to other channels. For example, if you wanted each element of your map to have a reference to the previous channel, you could do something like this:

// assumes that Map[whatever] is a struct with a "lastChan" field
var lastRef = chan my_type


for i := range Map {
      channel := make(chan my_type, buff_size)
      if(lastRef != nil){
          Map[i].lastChan = lastRef
      }

      go subroutine(Map[i], channel)
      lastRef = channel
}

func subroutine(name valueType, channel channelType) {
    //stuff here can access the previous channel with name.lastChan
}

Depending on what you want to do and which channels you need access to, you may wish to play around with the looping or even do mutliple loops.

Answered By – dethtron5000

Answer Checked By – David Marino (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.