du13932014807 2014-06-16 07:46
浏览 32
已采纳

并行循环

I want the for-loop to be parallel using go routines. i tried using channels but that didnt work. My main problem is, that i want to wait for all iterations to be finished before continuing. That's why simply writing go before it doesn't work. I tried to using channels (i think the wrong way) but that made my code even slower

func createPopulation(populationSize int, individualSize int) []Individual {
    population := make([]Individual, populationSize)

    //i want this loop to be work parallel
    for i := 0; i < len(population); i++ {
        population[i] = createIndividual(individualSize)
    }

    return population
}

func createIndividual(size int) Individual {
    var individual = Individual{make([]bool, size), 0}

    for i := 0; i < len(individual.gene); i++ {
        if rand.Intn(2)%2 == 1 {
            individual.gene[i] = true
        } else {
            individual.gene[i] = false
        }
    }

    return individual
}

My struct looks like this:

type Individual struct {
    gene []bool
    fitness int
}
  • 写回答

5条回答 默认 最新

  • dongza1708 2014-06-16 08:22
    关注

    So basically the goroutine should not return a value but push it down a channel. If you want to wait for all goroutines to finish you can just count to the number of goroutines, or use a WaitGroup. In this example it's an overkill because the size is known, but it's good practice anyway. Here's a modified example:

    package main
    
    import (
        "fmt"
        "math/rand"
        "sync"
    )
    
    type Individual struct {
        gene    []bool
        fitness int
    }
    
    
    func createPopulation(populationSize int, individualSize int) []Individual  {
    
        // we create a slice with a capacity of populationSize but 0 size
        // so we'll avoid extra unneeded allocations
        population := make([]Individual, 0, populationSize)
    
        // we create a buffered channel so writing to it won't block while we wait for the waitgroup to finish
        ch := make(chan Individual, populationSize)
    
        // we create a waitgroup - basically block until N tasks say they are done
        wg := sync.WaitGroup{}
    
        for i := 0; i < populationSize; i++ {
    
            //we add 1 to the wait group - each worker will decrease it back
            wg.Add(1)
    
            //now we spawn a goroutine
            go createIndividual(individualSize, ch, &wg)
        }
    
        // now we wait for everyone to finish - again, not a must.
        // you can just receive from the channel N times, and use a timeout or something for safety
        wg.Wait()
    
        // we need to close the channel or the following loop will get stuck
        close(ch)
    
        // we iterate over the closed channel and receive all data from it
        for individual := range ch {
    
            population = append(population, individual)
        }
        return population
    
    }   
    
    func createIndividual(size int, ch chan Individual, wg *sync.WaitGroup) {
    
        var individual = Individual{make([]bool, size), 0}
    
        for i := 0; i < len(individual.gene); i++ {
            if rand.Intn(2)%2 == 1 {
                individual.gene[i] = true
            } else {
                individual.gene[i] = false
            }
        }
    
        // push the population object down the channel
        ch <- individual
        // let the wait group know we finished
        wg.Done()
    
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作