猿问

无互斥量。

好吧,去“专家”。你会如何用惯用的 Go 编写这段代码,也就是没有互斥锁next?


package main


import (

    "fmt"

)


func main() {

    done := make(chan int)

    x := 0

    for i := 0; i < 10; i++ {

        go func() {

            y := next(&x)

            fmt.Println(y)

            done <- 0

        }()

    }

    for i := 0; i < 10; i++ {

        <-done

    }

    fmt.Println(x)


}


var mutex = make(chan int, 1)


func next(p *int) int {

    mutex <- 0

    // critical section BEGIN

    x := *p

    *p++

    // critical section END

    <-mutex

    return x


}

假设你不能同时在临界区有两个 goroutine,否则会发生不好的事情。


我的第一个猜测是有一个单独的 goroutine 来处理状态,但我想不出匹配输入/输出的方法。


扬帆大鱼
浏览 184回答 2
2回答

墨色风雨

您将使用实际的 sync.Mutex:var mutex sync.Mutexfunc next(p *int) int {&nbsp; &nbsp; mutex.Lock()&nbsp; &nbsp; defer mutex.Unlock()&nbsp; &nbsp; x := *p&nbsp; &nbsp; *p++&nbsp; &nbsp; return x}尽管您可能还会将next功能、状态和 sync.Mutex 组合到一个结构中。虽然在这种情况下没有理由这样做,因为 Mutex 更适合围绕单个资源进行互斥,您可以使用 goroutines 和通道来实现相同的效果http://play.golang.org/p/RR4TQXf2ctx := 0var wg sync.WaitGroupsend := make(chan *int)recv := make(chan int)go func() {&nbsp; &nbsp; for i := range send {&nbsp; &nbsp; &nbsp; &nbsp; x := *i&nbsp; &nbsp; &nbsp; &nbsp; *i++&nbsp; &nbsp; &nbsp; &nbsp; recv <- x&nbsp; &nbsp; }}()for i := 0; i < 10; i++ {&nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; send <- &x&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(<-recv)&nbsp; &nbsp; }()}wg.Wait()fmt.Println(x)

守着星空守着你

正如@favoretti 提到的,同步/原子是一种方法。但是,您必须使用 int32 或 int64 而不是 int (因为 int 在不同平台上的大小可能不同)。这是Playground上的一个例子package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync/atomic")func main() {&nbsp; &nbsp; done := make(chan int)&nbsp; &nbsp; x := int64(0)&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y := next(&x)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(y)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; done <- 0&nbsp; &nbsp; &nbsp; &nbsp; }()&nbsp; &nbsp; }&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp; <-done&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println(x)}func next(p *int64) int64 {&nbsp; &nbsp; return atomic.AddInt64(p, 1) - 1}
随时随地看视频慕课网APP

相关分类

Go
我要回答