Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Simulating waitgroups using Go atomics

I have the following code to spawn a number of Goroutines. Each Goroutine does a variable amount of work (simulated here by different loop lengths) and then atomically sets a variable in its job structure to signal its done. The main() Goroutine checks all the job structures for completion using compare_and_swap. This code is racy, the variable finish goes beyond numjobs, and I don’t understand why.

I know I can use waitgroups to achieve this, however, I want to understand why this fails.

type job struct {
    id    int
    done  uint32
    loops int
}

const (
    numjobs int = 10000
)

func (j *job) work() {
    for k := 0; k < j.loops; k++ {

    }
    fmt.Printf("Ending job %d\n", j.id)
    atomic.StoreUint32(&j.done, 1)

}
func main() {
    // Memory for jobs
    jobs := make([]job, numjobs)

    // Kick off the jobs, each running a random number of loops
    for i := 0; i < numjobs; i++ {
        jobs[i].id = i
        jobs[i].loops = rand.Intn(1000000)
        go (&jobs[i]).work()
    }

    // Track when all jobs are done
    finish := 0
    for finish != numjobs {
        for _, job := range jobs {
            if atomic.CompareAndSwapUint32(&job.done, 1, 0) {
                finish++
            }
        }
        fmt.Printf("Finished %d jobs\n", finish)
    }

}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You are updating a copy of the job. Try this:

       for job := range jobs {
            if atomic.CompareAndSwapUint32(&jobs[job].done, 1, 0) {
                finish++
            }
        }
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading