mutex&chan

保证同步访问共享资源的安全访问,消除竞争状态的方式有三种: 原子函数、互斥锁、通道

无缓冲通道:
当一个goroutine向通道发送,此时没有goroutine接收时,会导致发送goroutine阻塞,只有通道被接收后。两个goroutine才被释放出来,可以去处理各自的工作。任意一个操作都无法离开另一个操作单独存在。

互斥锁

互斥锁用于在代码上创建一个临界区,保证同一时间只有一个goroutine可以执行这个临界区代码。

package main

import (
    "fmt"
    "runtime"
    "sync"
)

var (
    counter int
    wg      sync.WaitGroup
    mutex   sync.Mutex
)

func main() {
    wg.Add(2)       //表示要等待2个goroutine
    go incCounter(1)
    go incCounter(2)

    wg.Wait()   //等待goroutine结束
    fmt.Printf("Final Counter:%d\n", counter)
}

func incCounter(id int) {
    defer wg.Done()  //在函数退出时,调用Done来通知main函数工作已经完成,goroutine结束
    for count := 0; count < 2; count++ {
        mutex.Lock()      //加锁,创建临界区
        value := counter
        runtime.Gosched()
        value++
        counter = value
        mutex.Unlock()  //解锁
    }
}
output:
    Finale Counter:4

无缓冲通道

在网球比赛中,两位选手会把球在两个人之间来回传递。选手总是处在以下两种状态之一:要么在等待接球,要么将球打向对方。使用两个goroutine来模拟网球比赛中的两个人,使用无缓冲通道来模拟球的来回。
当一方接球失败,关闭通道。另一方收到通道关闭,则说明自己won

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

var wg sync.WaitGroup

//init函数在main函数之前运行
func init() {
    /* 初始化随机数种子,默认随机数种子为Seed(1),对程序而言属于产生伪随机数。
    即当程序每次重新开始运行,结果都一致。
    选定不同的随机种子,每次运行产生不一样的随机数。 
    */
    rand.Seed(time.Now().UnixNano())
}


func main() {
    court := make(chan int) //无缓存通道,模拟网球
    wg.Add(2)  //等待两个goroutine
    go player("Vera", court)  //选手Vera
    go player("hannah", court)  //选手Hannah
    court <- 1    //发球
    wg.Wait()  //等待游戏结束
}

func player(name string, court chan int) {
    defer wg.Done()  //函数退出时通知main函数goroutine已结束
    for {
        ball, ok := <-court    //等待球被打过来,接球
        if !ok {       //接收到通道关闭,则赢了
            fmt.Printf("player %s won\n", name)
            return
        }

       //选择随机数,利用这个数来判断是否球是否接到
        n := rand.Intn(100) 
        if n%13 == 0 {   //没接到球
            fmt.Printf("player %s Missed\n", name)
            close(court)   //关闭通道,游戏结束
            return
        }

        //接到球,继续打
        fmt.Printf("player %s Hit %d\n", name, ball)
        ball++
        court <- ball  //将球打向对方
    }
}
output:
    player hannah Hit 1
    player Vera Hit 2
    player hannah Hit 3
    player Vera Hit 4
    player hannah Missed
    player Vera won
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值