网页和网站有什么分别,做盗版电影网站后果,wordpress文章一部分加密,2022年最火的网页游戏代码例子
下面代码的区别是直接调用循环变量#xff0c;这里使用的就是这个变量的引用#xff0c;而不是将参数的副本传递给协程执行
for task : range taskChan {wg.Add(1)go func() {defer wg.Done()task.Do() // 使用外部循环变量}()
}func DistributeTasks(taskChan 这里使用的就是这个变量的引用而不是将参数的副本传递给协程执行
for task : range taskChan {wg.Add(1)go func() {defer wg.Done()task.Do() // 使用外部循环变量}()
}
func DistributeTasks(taskChan -chan *AddTask, resChan chan int) {var wg sync.WaitGroupfor task : range taskChan {wg.Add(1)go func(t *AddTask) {defer wg.Done()t.Do()}(task) // 注意要当作参数传入而不是直接在 开启的协程 内部调用task}wg.Wait()close(resChan)
}
结论
可能导致的问题 在 Go 语言中当你使用 go 关键字启动一个 goroutine 时它会在一个新的并发执行单元中运行。在原始代码中将 task 作为参数传递给匿名函数确保了每个 goroutine 操作的 task 是独立的因为函数参数是按值传递的这意味着在 go 语句执行时会将 task 的副本传递给匿名函数。如果不将 task 作为参数传递而是直接在匿名协程 goroutine 中调用 task由于 goroutine 可能会在 for 循环的下一次迭代开始后才开始执行而 for 循环会不断更新 task 的值这可能会导致 goroutine 看到的 task 值不是你期望的那个。例如goroutine执行时间很长而程序中开启goroutine是一个很快的过程开启完毕之后就执行下一次for循环了循环变量task也就变了之前开启的goroutine执行到task.Do() 的时候已经是其他次循环的task变量
for task : range taskChan {wg.Add(1)go func() {defer wg.Done()//假如这里有比较久的耗时操作task.Do() // 使用外部循环变量这时候可能已经当时那一次循环的task了因为开启协程这段代码一下子就执行完毕}()
}