20

通道将通信(值的交换)与同步相结合,确保两个计算(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()
}
4

2 回答 2

29

使用 Channel 作为 Mutex 的示例:

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 的评论。

于 2010-10-17T11:36:52.727 回答
5

如果您有一个c使用 1 项初始化的通道,那么您可以通过从通道 ( <-c) 中删除值来“签出”“互斥锁”。您可以通过将值加回 ( c <- 1) 来“释放”它。

由于从通道中提取操作符 a) 是原子的,并且 b) 阻塞直到有东西要提取,所以它作为互斥体工作,因为如果一个执行线程已经将其签出,通道中将没有任何内容,并且因此它将阻塞,直到检查它的线程将一个值返回到通道以供另一个线程提取。

于 2010-10-17T05:19:55.497 回答