通道将通信 - 值的交换 - 与同步相结合 - 保证两个计算(goroutines)处于已知状态。
如何使用Google Go中的频道执行互斥功能?
package main
import "sync"
var global int = 0
var m sync.Mutex
func thread1(){
m.Lock()
global = 1
m.Unlock()
}
func thread2(){
m.Lock()
global = 2
m.Unlock()
}
func main(){
go thread1()
go thread2()
}
答案 0 :(得分:22)
将频道用作互斥锁的示例:
package main
var global int = 0
var c = make(chan int, 1)
func thread1(){
<-c // Grab the ticket
global = 1
c <- 1 // Give it back
}
func thread2(){
<-c
global = 2
c <- 1
}
func main() {
c <- 1 // Put the initial value into the channel
go thread1()
go thread2()
}
您还可以使用chan struct{}
代替chan int
来减少内存大小。其中包含的值为struct{}{}
(类型struct{}
和空内容{}
)。有关示例,请参阅Ivan black's comment。
答案 1 :(得分:5)
如果你有一个频道c
,你初始化其中包含1个项目,那么你可以通过删除频道(<-c
)中的值来“检出”“互斥”。您可以通过添加值(c <- 1
)来“释放”它。
由于来自通道的提取操作符a)是原子的,并且b)阻塞直到有东西被提取,它起到互斥的作用,因为如果一个执行的线程已经检出它,那么就没有了通道,因此它将阻塞,直到检出它的线程将一个值返回到通道以供另一个线程提取。