并行For循环

前端之家收集整理的这篇文章主要介绍了并行For循环前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想使用go例程将for循环并行.我试过使用频道,但没有用.我的主要问题是,我希望在继续之前等待所有迭代完成.这就是为什么简单地写之前它不起作用.我试图使用频道(我认为是错误的方式),但这使我的代码更慢
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
}

我的结构看起来像这样:

type Individual struct {
    gene []bool
    fitness int
}

解决方法

所以基本上goroutine不应该返回一个值,而是将其推向一个通道.如果你想等待所有goroutine完成,你可以只计算goroutines的数量,或使用WaitGroup.在这个例子中,它是一种矫枉过正,因为它的大小是众所周知的,但无论如何它都是很好的做法.这是一个修改过的例子:
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,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,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()

}

猜你在找的Java相关文章