如果我正确使用频道,我是否需要使用互斥锁来防止并发访问?
答案 0 :(得分:9)
如果正确使用频道,则不需要互斥锁。在某些情况下,使用互斥锁的解决方案可能更简单。
在多个goroutine尝试访问通道变量之前,只需确保保存通道值的变量已正确初始化。完成此操作后,访问通道(例如,向其发送值或从中接收值)是安全的。
支持带参考文件(由我添加的重点):
send statements,receive operations中可以使用单个频道 ,并调用内置函数
cap
和len
任意数量的goroutines没有进一步同步。频道充当先进先出队列。例如,如果一个goroutine在一个通道上发送值而另一个goroutine接收到它们,则按发送的顺序接收这些值。
Effective Go: Concurrency: Share by communicating
实现对共享变量的正确访问所需的微妙之处使许多环境中的并发编程变得困难。 Go鼓励采用一种不同的方法,在这种方法中,共享值在通道上传递,实际上,不会由单独的执行线程主动共享。 在任何给定时间只有一个goroutine可以访问该值。数据竞赛不可能通过设计发生。为了鼓励这种思维方式,我们将其缩小为一个口号:
不要通过共享内存进行通信;相反,通过沟通来分享记忆。
这种方法可以采取太多措施。例如,可以通过在整数变量周围放置互斥量来最好地完成引用计数。但作为一种高级方法,使用通道来控制访问可以更容易地编写清晰,正确的程序。
这篇文章也非常有用:The Go Memory Model
同样引用sync
的包文档:
包同步提供基本同步原语,例如互斥锁。除了Once和WaitGroup类型之外,大多数都适用于低级库例程。通过频道和通信可以更好地完成更高级别的同步。