go语言--竞争、原子函数、互斥锁

一、go语言竞争状态、原子函数、互斥锁

下面代码例子是展示并发下公共数据操作,通过原子函数和互斥锁怎么解决。

package main

import (
    "sync"
    "runtime"
    "fmt"
    "sync/atomic"
)

var(
    // counter是所有goroutine都要增加的变量
    counter int64
    // wg用来等待程序的结束
    wg sync.WaitGroup
    // mutex 用来定义一段代码临界区
    mutex sync.Mutex
)

func main() {
    // 计数加2,表示要等待两个goroutine
    wg.Add(2)
    // 创建两个goroutine
    go incCounter(1)
    go incCounter(2)
    // 等待goroutine结束
    wg.Wait()
    fmt.Println("Final Counter:", counter)
}

// incCounter增加包里counter变量的值
func incCounter(id int) {
    // 延时调用,在函数退出时调用Done来通知main函数工作已经完成
    defer wg.Done()

    for count := 0; count < 2; count++ {
        // 捕获counter的值
        value := counter
        // 当前goroutine从线程退出,并放回到队列
        runtime.Gosched()
        // 增加本地value变量的值
        value++
        // 将该值保存回counter
        counter = value
    }
}
// incCounter增加包里counter变量的值
func incCounter1(id int) {
    defer wg.Done()

    for count := 0; count < 2; count++ {
        // 安全的对counter加1
        atomic.AddInt64(&counter, 1)
        // 当前goroutine从线程退出,并放回到队列
        runtime.Gosched()
    }
}

// incCounter增加包里counter变量的值
func incCounter2(id int) {
    // 延时调用,在函数退出时调用Done来通知main函数工作已经完成
    defer wg.Done()

    for count := 0; count < 2; count++ {
        // 同一时刻只允许一个goroutine进入这个临界区
        mutex.Lock()
        {
            // 捕获counter的值
            value := counter
            // 当前goroutine从线程退出,并放回到队列
            runtime.Gosched()
            // 增加本地value变量的值
            value++
            // 将该值保存回counter
            counter = value
        }
        // 释放锁,允许其他正在等待的goroutine进入临界区
        mutex.Unlock()
    }
}
  • 下面图片是竞争状态下的数据交互模型

1406089-20190924100554594-1214426108.png

转载于:https://www.cnblogs.com/wudiffs/p/11576683.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值