Golang 如何使用原子函数修复竞态条件

Golang 如何使用原子函数修复竞态条件

在一个系统中,两个或多个执行过程会具有并发的幻觉,访问共享数据时可能会同时试图更改共享数据。系统中的这种情况称为竞态条件。关于Golang中竞态条件的示例代码可以参考本文。

Golang中的原子包提供了用于同步访问指针和整数等的低级锁定机制。使用atomic/sync包函数可以解决竞态条件问题。

示例:

// 通过使用原子包修复竞态条件的Golang程序
package main
  
import (
    "fmt"
    "runtime"
    "sync"
    "sync/atomic"
)
  
// 所有的goroutine都将增加变量c
// waitgroup等待程序完成。
var (
    c         int32
    waitgroup sync.WaitGroup
)
  
func main() {
  
    // 使用Add()函数帮助为每个goroutine添加一个
    // 共计3个计数
    waitgroup.Add(3)
  
    // 使用increment()函数增加
    // 两次操作
    go increment("geeks")
    go increment("for")
    go increment("geeks")
  
    // 等待goroutine完成。
    waitgroup.Wait()
  
    // 输出计数器
    fmt.Println("Counter:", c)
  
}
  
func increment(name string) {
  
    // Done()函数用于
    // 声明它已经完成。
    defer waitgroup.Done()
  
    for range name {
  
        // 原子函数
        // 用于修复竞态条件
        atomic.AddInt32(&c, 1)
  
        // 线程挂起
        runtime.Gosched()
    }
} 
Go

输出:

Counter: 13
Go

在这里,我们使用了 atomic.AddInt32() 函数同步增加整数值,这样只有一个goroutine允许完成一次加法操作。记住一点,始终使用在线编译器检查此类程序的输出,因为由于确定性的特性,您可能每次都会得到相同的输出(表示没有竞态条件)。因此,请使用诸如Visual Studio或CMD之类的本地编译器来查看结果。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册