我听说channel
优于sycn.Mutex.Lock()
当您的程序具有高并发性时。但是为什么 channel 更有效率呢?在我看来,要实现一个安全的缓冲池(我认为 channel 可以被认为是一个缓冲池),你必须使用锁。
如果 channel
效率更高,为什么有sycn.Mutex
?因为我可以写下面的代码来模拟sync.Mutex
.
type seme struct {
lock chan int
locked bool
}
func (l *seme)Lock() {
// state 0 for initial, 1 for locked, 2 for free.
if atomic.CompareAndSwapInt32(&l.state, 0, 1) {
l.lock = make(chan int, 1)
}
l.lock <- 0
l.state = 1
}
func (l *seme)UnLock() {
if !atomic.CompareAndSwapInt32(&l.state, 1, 2) {
panic("UnLock a free Lock")
}
l.state = 2
<- l.lock
}
如果
channel
到处都比mutex
好, 为什么要使用 mutex
?也就是说,什么时候应该使用mutex
但不是 channel
?有人可以给我一个例子吗?
最佳答案
channel 从根本上不同于互斥体。
一个有足够细节的正确答案会太长,所以让我们只介绍主要亮点,特别是在 Go channel 方面:
sync.Mutex
为并发例程(goroutines)之间的共享内存提供互斥。 数据传输表示复制某个类型 T 的值。Goroutine A 将一个值放入 channel 中:
var v T // v is a value of type T
...
ch <- v // put v's value into the channel
何时以及是否尝试放置
v
进入 channel block ,如果你愿意,你可以做些什么,有点复杂,但如果 channel 被缓冲,那么至少一些值可以立即进入它而没有任何阻塞,以便发送 goroutine 可以继续.如果 channel 没有缓冲,发送方会阻塞,直到某个接收方 goroutine 正在积极等待一个值。 (有时这是可取的,有时则不是。)同时,goroutine B 从 channel 中取出一个值:
var w T // w is also a value of type T
...
w <- ch
要不就:
w :=<- ch
同样,何时以及是否会阻塞,您可以做什么,何时应该做某事等,可能会变得复杂;但在简单的情况下,这会等待有一个可用的值——让某个 goroutine 执行
ch <- v
,或者如果 channel 被缓冲,则已经完成了 - 然后它复制到变量 w
放入 channel 的值。变量 v
可能已经改变,甚至在这一点上被完全摧毁。该值已安全存储在 channel 中,现在已从 channel 中删除并放入变量 w
.Go channel 有一些额外的功能,例如关闭 channel 的能力,它可以防止进一步的写入,并将“数据结束”通知传递给读取操作。这可以通过单值读取 (
w, ok <- ch
) 进行测试,并且在 for w := range ch
中进行了隐式测试。环形。一个
sync.Mutex
例如,相比之下,您只需调用 Lock
和 Unlock
.它不保存任何排队的值(如缓冲 channel 那样),甚至也没有防止您意外发送 sync.Mutex
的类型(float
本身除外)。期待string
管他呢。这个锁的存在让两个或多个 goroutine 使用共享内存区域来完成某些事情。channel 的运行时实现很可能需要某种互斥锁。这不一定是
sync.Mutex
本身:任何提供足够互斥的东西就足够了。在 the Go channel implementation you are probably using ,它不是 sync.Mutex
而是专门的runtime mutex . (请注意,此链接指向特定行,并且该行可能会随着时间的推移而过时。)由于某些 channel 代码是由编译器本身直接生成的,因此不应假定此处的运行时例程正在使用:您的编译器可能与众不同。然而,研究这个特定的实现可能会让您对您可以使用 channel 做什么有所启发。互斥锁通常比 channel 简单得多。要查看示例,请将上述 channel 实现中的代码量(不包括编译器的内联插入)与此特定 Go 实现的
sync.Mutex
source code 进行比较。 .
关于multithreading - Golang 中的 channel 和 mutex 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61420524/