Golang 中的 channel 和 mutex 有什么区别?

我听说这channel比sycn.Mutex.Lock()您的程序具有高并发性时要好。但是为什么渠道更有效率呢?在我看来,要实现一个安全的缓冲池(我认为通道可以被认为是一个缓冲池),你必须使用锁。


如果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?有人可以给我一个例子吗?


倚天杖
浏览 202回答 2
2回答

catspeake

通道从根本上不同于互斥体。一个有足够细节的正确答案会太长,所以让我们只介绍主要亮点,特别是在 Go 频道方面:Go 通道提供并发例程(goroutines)之间的类型化数据传输。A为并发例程(goroutines)之间的共享内存sync.Mutex提供互斥。数据传输表示复制某个类型 T 的值。Goroutine A 将一个值放入通道中:var v T&nbsp; // v is a value of type T...ch <- v&nbsp; // put v's value into the channel何时以及是否尝试放入v 通道块,以及如果您愿意,您可以对此做些什么,有点复杂,但如果通道是缓冲的,那么至少一些值可以立即进入它而没有任何阻塞,以便发送 goroutine 可以继续。如果通道是无缓冲的,则发送方会阻塞,直到某个接收方 goroutine 正在积极等待一个值。(有时这是可取的,有时则不是。)同时,goroutine B 从通道中取出一个值:var w T&nbsp; // w is also a value of type T...w <- ch要不就:w :=<- ch同样,何时以及是否会阻塞,您可以做什么,何时应该做某事等,可能会变得复杂;但在简单的情况下,这会等待有一个可用的值——让某个 goroutine 执行ch <- v,或者如果通道被缓冲,则已经完成它——然后它将放入w通道中的值复制到变量中。变量v可能已经改变,甚至被完全破坏。该值已安全地存储在通道中,现在已从通道中删除并放入变量w中。Go 通道有一些额外的功能,例如关闭通道的能力,它可以防止进一步的写入,并将“数据结束”通知传递给读取操作。这可以通过单值读取 ( ) 进行测试,并在循环w, ok <- ch中进行隐式测试。for w := range chsync.Mutex相比之下,实例只是让您调用Lockand Unlock。它不保存任何排队的值(如缓冲通道那样),甚至没有一种类型(除了sync.Mutex它自己),可以防止您意外地将 a 发送float到期望的东西string或其他东西。这个锁的存在让两个或多个 goroutine 使用共享内存区域来完成某些事情。通道的运行时实现很可能需要某种互斥锁。这不一定是sync.Mutex它本身:任何提供足够互斥的东西就足够了。在您可能正在使用的 Go 通道实现中,它不是一个专门的运行时互斥锁sync.Mutex,而是一个专用的运行时互斥锁。(请注意,此链接指向特定行,并且该行可能会随着时间的推移而过时。)由于某些通道代码是由编译器本身直接生成的,因此不应假定此处的运行时例程正在使用:您的编译器可能与众不同。然而,研究这个特定的实现可能会让您对您可以使用通道做什么有所启发。互斥锁通常比通道简单得多。要查看示例,请将上述通道实现中的代码量(不包括编译器的内联插入)与此特定 Go 实现的sync.Mutex源代码进行比较。

呼唤远方

在 Golang 的并发程序中有两种通信方式。同步包:通过共享内存进行通信。渠道:通过交流共享记忆。去推荐不要通过共享内存进行通信。相反,通过通信共享内存。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go