上代码, 自己品
package main
import "fmt"
func main() {
// 不会打印任何内容, 因为代码执行完, 主 goroutine 就退出了. 其他的 goroutine 还没有机会执行, 程序就结束了
for i := 0; i < 10; i++ {
go func() {
fmt.Println(i)
}()
}
}
package main
import (
"fmt"
"time"
)
func main() {
// 可以打印 10 个数, 但 不是 0 ~ 9
for i := 0; i < 10; i++ {
go func() {
fmt.Println(i)
}()
}
time.Sleep(time.Second)
}
package main
import (
"fmt"
)
func main() {
// 可以打印 0 ~ 9, 但是 乱
r := make(chan struct{}, 10)
for i := 0; i < 10; i++ {
go func(i int) {
fmt.Println(i)
r <- struct{}{}
}(i) // 把 i 当参数传进去, 函数里面可以得到 i 的副本, 所以可以打印 0 ~ 9
}
for i := 0; i < 10; i++ {
<-r
}
}
package main
import (
"fmt"
"sync"
)
func main() {
// 可以打印 0 ~ 9, 但是 乱
wg := sync.WaitGroup{}
wg.Add(10)
for i := 0; i < 10; i++ {
go func(i int) {
fmt.Println(i)
wg.Done()
}(i) // 把 i 当参数传进去, 函数里面可以得到 i 的副本, 所以可以打印 0 ~ 9
}
wg.Wait()
}
package main
import (
"fmt"
"sync/atomic"
"time"
)
var count uint32 = 0
func trigger(i uint32, fn func()) {
for {
// 进来后, 如果 i > count, 会睡一会, 一直到时 i == count 才会执行, 执行完, 返回
// LoadUint32, AddUint32 是并发安全的
if n := atomic.LoadUint32(&count); n == i {
fn()
atomic.AddUint32(&count, 1)
break
}
time.Sleep(time.Nanosecond)
}
}
func main() {
// 按顺序打印
for i := uint32(0); i < 10; i++ {
go func(i uint32) {
trigger(i, func() {
fmt.Println(i)
})
}(i)
}
// 会等到 10 的时候才会返回
trigger(10, func() {})
}