且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如果我正确使用通道,我是否需要使用互斥锁?

更新时间:2023-11-13 23:11:40

如果正确使用通道,则不需要互斥锁.在某些情况下,使用互斥锁的解决方案可能更简单.

You don't need mutex if you use channels correctly. In some cases a solution with mutex might be simpler though.

在多个 goroutine 尝试访问通道变量之前,请确保正确初始化保存通道值的变量.完成此操作后,访问通道(例如向它们发送值或从它们接收值)在设计上是安全的.

Just make sure the variable(s) holding the channel values are properly initialized before multiple goroutines try to access the channel variables. Once this is done, accessing the channels (e.g. sending values to or receiving values from them) is safe by design.

带有参考文献的支持文件(重点是我加的):

Supporting documents with references (emphases added by me):

规范:频道类型:

发送语句

可以使用单通道接收操作,并调用内置函数caplen 通过任意数量的 goroutines 无需进一步同步.通道充当先进先出队列.例如,如果一个 goroutine 在通道上发送值,而第二个 goroutine 接收它们,则按照发送的顺序接收值.

A single channel may be used in send statements, receive operations, and calls to the built-in functions cap and len by any number of goroutines without further synchronization. Channels act as first-in-first-out queues. For example, if one goroutine sends values on a channel and a second goroutine receives them, the values are received in the order sent.

Effective Go:并发:通过交流分享

在许多环境中并发编程变得困难,因为实现对共享变量的正确访问所需的微妙之处.Go 鼓励一种不同的方法,在这种方法中,共享值在通道上传递,实际上,从不由单独的执行线程主动共享.在任何给定时间只有一个 goroutine 可以访问该值.数据竞争不可能发生,这是设计使然.为了鼓励这种思维方式,我们将其简化为一个口号:

Concurrent programming in many environments is made difficult by the subtleties required to implement correct access to shared variables. Go encourages a different approach in which shared values are passed around on channels and, in fact, never actively shared by separate threads of execution. Only one goroutine has access to the value at any given time. Data races cannot occur, by design. To encourage this way of thinking we have reduced it to a slogan:

不要通过共享内存进行通信;相反,通过通信共享内存.

这种方法可能太过分了.例如,***通过在整数变量周围放置互斥锁来完成引用计数.但作为一种高级方法,使用通道来控制访问可以更轻松地编写清晰、正确的程序.

This approach can be taken too far. Reference counts may be best done by putting a mutex around an integer variable, for instance. But as a high-level approach, using channels to control access makes it easier to write clear, correct programs.

这篇文章也很有帮助:Go Memory Model

还引用了 sync 的包文档:

Also quoting from the package doc of sync:

Package sync 提供了基本的同步原语,例如互斥锁.除了Once 和WaitGroup 类型之外,大多数都旨在供低级库例程使用.更高级别的同步***通过渠道和沟通来完成.

Package sync provides basic synchronization primitives such as mutual exclusion locks. Other than the Once and WaitGroup types, most are intended for use by low-level library routines. Higher-level synchronization is better done via channels and communication.