Parallel for loop

I want to use the go routine to parallelize the for loop I tried to use the channel, but it didn't work My main problem is that I want to wait for all iterations to complete before continuing That's why it doesn't work until it's simply written I tried to use the channel (I think it was the wrong way), but it made my code 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 structure looks like this:

type Individual struct {
    gene []bool
    fitness int
}

Solution

So basically goroutine should not return a value, but push it to a channel If you want to wait for all goroutines to complete, you can only calculate the number of goroutines, or use waitgroup In this case, it's an overreaction because its size is well known, but it's a good practice anyway This is 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,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()

}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>