Go-goroutine 的那些事

上代码, 自己品

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() {})
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值