Skip to content

code for concurrency has race condition #877

@hughlunnon

Description

@hughlunnon

I'm learning go here, so might be way off the mark on this :)

the code in this block

package concurrency

type WebsiteChecker func(string) bool
type result struct {
	string
	bool
}

func CheckWebsites(wc WebsiteChecker, urls []string) map[string]bool {
	results := make(map[string]bool)
	resultChannel := make(chan result)

	for _, url := range urls {
		go func() {
			resultChannel <- result{url, wc(url)}
		}()
	}

	for i := 0; i < len(urls); i++ {
		r := <-resultChannel
		results[r.string] = r.bool
	}

	return results
}

doesn't pass the initial (correctness) test - all the values within the channel have the last url and url result within them. I actually get a warning in goland about the code

Image

I don't fully understand that message but I think the value of the url is changing before the goroutine has had a chance to execute. There is more info here.

The below code passes all tests

	for _, url := range urls {
		finalUrl := url
		go func() {
			resultChannel <- result{finalUrl, wc(finalUrl)}
		}()
	}

I haven't raised a PR as my code might not be the "correct" answer, but welcome any feedback

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions