美文网首页
Go 中的协程同步2

Go 中的协程同步2

作者: 浑浑噩噩_邋邋遢遢 | 来源:发表于2017-08-01 08:58 被阅读0次
chan同步

继续上一篇的协程同步,我们发现主程序里用了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())
}
waitgroup

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())
}

相关文章

  • Go 中的协程同步2

    chan同步 继续上一篇的协程同步,我们发现主程序里用了sleep等待所有任务执行完毕。这样显然不够好,那么继续寻...

  • Go 中的协程同步(锁)

    先来看一个简单的例子,在不运行的前提下猜测结果是什么这里模仿两个人同时刷卡的操作,猜测最后剩余多少钱 结果为-1....

  • 21. Go 协程

    21. Go 协程 Go 协程是什么? Go 协程是与其他函数或方法一起并发运行的函数或方法。Go 协程可以看作是...

  • Go协程介绍

    参考自《go专家编程》Go协程所实现的是M:N的线程模型,M个协程运行在N个线程中。 1. MPG模型 Go协程中...

  • golang学习笔记(十)并发

    1、goroutine (1)通过go关键字创建一个协程(2)主协程退出后,子协程也会退出 2、runtime包 ...

  • Kotlin协程使用

    目录 协程的用法 协程同步异步请求与Rxjava,原生写法的区别与优势 对于协程的理解 1.协程的用法 在安卓中添...

  • go的协程并发-channel消息机制

    go的协程并发-channel消息机制 方式一 方式二 go-协程实现方案汇总

  • 简易协程-3

    新增的功能 在《简易协程-2》的基础上增加协程同步等待、IO超时的支持。增加一个新类JoinAction支持协程同...

  • 随笔33号20180930-go协程小tips

    启动一个新的协程时,协程的调用会立即返回。与函数不同,程序控制不会去等待 Go 协程执行完毕。在调用 Go 协程之...

  • 一个简易gopool框架

    提纲 目标 效果图 传送门 目标 在 go 中起协程是非常方便的, 节省资源的, 协程栈大小最大为2KB, 所以乍...

网友评论

      本文标题:Go 中的协程同步2

      本文链接:https://www.haomeiwen.com/subject/xdgdlxtx.html