Go语言提供了传统的同步 goroutine 的机制,就是对共享资源加锁。如果需要顺序访问一个整型变量或者一段代码,atomic 和 sync 包里的函数提供了很好的解决方案。
1.原子函数
原子函数能够以很底层的加锁机制来同步访问整型变量和指针。

运行结果

这个程序使用了 atomic 包的 AddInt64 函数。这个函数会同步整型值的加法,方法是强制同一时刻只能有一个 goroutine 运行并完成这个加法操作。当 goroutine 试图去调用任何原子函数时,这些 goroutine 都会自动根据所引用的变量做同步处理。
2.互斥所
另一种同步访问共享资源的方式是使用互斥锁(mutex)。互斥锁用于在代码上创建一个临界区,保证同一时间只有一个 goroutine 可以执行这个临界区代码。
//这个示例程序展示如何使用互斥锁来定义一段需要同步访问的代码临界区。
//资源的同步访问

运行结果:

对 counter 变量的操作使用 Lock() 和 Unlock() 函数调用定义的临界区保护起来。使用大括号并不是必须的,只是为了让临界区看起来更清晰。同一时刻只有一个 goroutine 可以进入临界区。之后,直到调用 Unlock() 函数之后,其他 goroutine 才能进入临界区。
网友评论