在Go语言中使用由`for`循环创建的通道。

huangapple go评论92阅读模式
英文:

Using channels in Go created by a 'for' loop

问题

for循环中创建的通道能否被从该for循环并发运行的子例程互换使用?

伪代码如下:

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

    go subroutine(Map[i], channel)
}

func subroutine(name valueType, channel channelType) {
    // 这里是一些操作
}

是否有一种方式,例如subroutine(Map[0]),可以访问在for循环的另一个迭代期间创建的另一个通道,即subroutine(Map[1])的通道?


背景:我目前正在一个项目中工作,需要模拟不同的细胞群体。每个细胞都具有分裂、分化等能力。为了复制真实系统,不同的细胞群体必须同时运行。问题是,在处理不同的细胞群体时,我必须插入/删除特定类型的细胞,这就是通道发挥作用的地方。我想同时运行这些细胞群体,每个细胞群体都有一个关联的通道。这就是我问的是否可以在不同的for循环迭代中使用创建的通道的原因。


以下是一些支持我上述背景描述的代码,其中包含了解释不同元素的注释。我已经包含了通道,但我不知道它是否有效。我希望这有助于理解我想要做的事情:

func main() {
    // envMap是一个map[int]Population,Population是一个结构体
    envMap := initialiseEnvironment(envSetupInfo)

    // 通用模拟循环
    for i := 0; i < 10; i++ {
        // 循环并行处理所有envMap元素
        for eachKey := range envMap {
            channel := make(chan type)
            go simulateEnv(envMap[eachKey])
        }
    }
}

func simulateEnv(cellPopulation Population, channel chan) {
    // 每个Population都有一个map[int]Cell,Cell是一个具有细胞属性的结构体
    cellMap := cellPopulation.cellMap

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

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])?

<hr/>

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.

<hr/>

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 &lt; 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)
    }
}

答案1

得分: 1

假设地图的每个元素都是一个结构体,你可以添加一个字段来保存对其他通道的引用。例如,如果你希望地图的每个元素都有一个对前一个通道的引用,你可以这样做:

// 假设 Map[whatever] 是一个带有 "lastChan" 字段的结构体
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) {
    // 在这里的代码可以通过 name.lastChan 访问前一个通道
}

根据你想要做什么以及你需要访问哪些通道,你可以尝试调整循环或进行多个循环。

英文:

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 &quot;lastChan&quot; 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.

huangapple
  • 本文由 发表于 2014年2月28日 01:50:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/22076404.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定