社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
继续上一篇的协程同步,我们发现主程序里用了sleep等待所有任务执行完毕。这样显然不够好,那么继续寻找其它答案来解决。。。
设想,当要执行多个任务时,如果每个任务在结束时返回给调用者一个完成的信号,那么我们就可以拿着所有返回的信号,与总任务个数做对比。这样就能知道任务究竟有没有执行完毕了,于是我们就利用chan的特性解决问题
package main
import (
"time"
"fmt"
"sync"
)
type Account struct {
flag sync.Mutex // 使用一种复用变量, 只有一个人锁住,其他人就会sleep 直到解锁
money int
}
func (a *Account)DoPre() {
time.Sleep(time.Millisecond) // 模仿银行进行检测
}
func (a *Account)GetGongzi(n int) {
a.money += n
}
func (a *Account) GiveWife(n int) {
a.flag.Lock() // 锁住
if a.money > n {
a.DoPre()
a.money -= n
}
a.flag.Unlock() // 释放锁
}
func (a *Account)Buy(n int) {
a.flag.Lock()
if a.money > n {
a.DoPre()
a.money -= n
}
a.flag.Unlock()
}
func (a *Account) Left() int {
return a.money
}
func main() {
var account Account
task_chan := make(chan int) // 创建专门接受信号的chan
account.GetGongzi(10)
go func() {
account.GiveWife(6)
task_chan <- 0 // 任务结束发送完成信号
}()
go func() {
account.Buy(5)
task_chan <- 0 // 发送完成信号
}()
for i :=0; i <2; i++ { // 循环接受chan数据 直到全部执行完毕
<- task_chan
}
fmt.Println(account.Left())
}
go里面还自带了一种用于协程同步的方案,它会自动的等待任务结束,并返回相应的信号
package main
import (
"time"
"fmt"
"sync"
)
type Accout struct {
lock sync.Locker
money int
}
func (a *Accout) DoPrepare() {
time.Sleep(time.Second)
}
func (a *Accout) GetGongZi(n int) {
a.money += n
}
func (a *Accout) GiveWife(n int) {
a.lock.Lock()
if a.money > n{
a.money -= n
}
a.lock.Unlock()
}
func (a *Accout) Buy(n int) {
a.lock.Lock()
if a.money > n{
a.money -= n
}
a.lock.Unlock()
}
func (a *Accout) Left() int {
return a.money
}
func main() {
var account Accout
account.GetGongZi(10)
wg := new(sync.WaitGroup) // 创建waitgroup
wg.Add(2) // add的个数要跟任务个数一致
go func() {
account.GiveWife(6)
wg.Done() // 任务执行完毕
}()
go func() {
account.Buy(5)
wg.Done()
}()
wg.Wait() // 等待所有任务执行完毕
fmt.Println(account.Left())
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!