learn go with tests 学习笔记(五)并发
2020-06-16 本文已影响0人
半亩房顶
知识点
缓慢的测试会破坏开发人员的生产力。
并发的竞争条件
fatal error: concurrent map writes
。有时候,当我们运行我们的测试时,两个 goroutines 完全同时写入 results
map。Go 的 Maps 不喜欢多个事物试图一次性写入,所以就导致了 fatal error
。
这是一种 race condition(竞争条件),当软件的输出取决于事件发生的时间和顺序时,因为我们无法控制,bug 就会出现。因为我们无法准确控制每个 goroutine 写入结果 map 的时间,两个 goroutines 同一时间写入时程序将非常脆弱。
Go 可以帮助我们通过其内置的 race detector 来发现竞争条件。要启用此功能,请使用 race
标志运行测试:go test -race
。
channels
我们可以通过使用 channels 协调我们的 goroutines 来解决这个数据竞争。channels 是一个 Go 数据结构,可以同时接收和发送值。这些操作以及细节允许不同进程之间的通信。
在这种情况下,我们想要考虑父进程和每个 goroutine 之间的通信,goroutine 使用 url 来执行 WebsiteChecker 函数。
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(u string) {
resultChannel <- result{u, wc(u)}
}(url)
}
for i := 0; i < len(urls); i++ {
result := <-resultChannel
results[result.string] = result.bool
}
return results
}
引用
欢迎大家关注我的公众号
半亩房顶