去互联网

时间:2015-09-26 09:46:11

标签: go concurrency

好的,Go"专家"。你会如何在惯用的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来处理状态,但我无法找到匹配输入/输出的方法。

2 个答案:

答案 0 :(得分:3)

您将使用实际的sync.Mutex:

var mutex sync.Mutex

func next(p *int) int {
    mutex.Lock()
    defer mutex.Unlock()
    x := *p
    *p++
    return x
}

虽然您可能还会将next功能,州和sync.Mutex分组到一个结构中。

虽然在这种情况下没有理由这样做,但由于Mutex更适合围绕单个资源进行互斥,因此您可以使用goroutines和channel来实现相同的效果

http://play.golang.org/p/RR4TQXf2ct

x := 0

var wg sync.WaitGroup
send := make(chan *int)
recv := make(chan int)

go func() {
    for i := range send {
        x := *i
        *i++
        recv <- x
    }
}()

for i := 0; i < 10; i++ {
    wg.Add(1)
    go func() {
        defer wg.Done()
        send <- &x
        fmt.Println(<-recv)
    }()
}
wg.Wait()
fmt.Println(x)

答案 1 :(得分:1)

正如@favoretti所提到的,同步/原子是一种方法。

但是,你必须使用int32或int64而不是int(因为int在不同的平台上可以是不同的大小)。

以下是Playground

的示例
(define (sort list length loop1 loop2 temp)
(cond ((>= loop1 length)
        (list))
     ((< loop1 length)
        (cond ((>= loop2 length)
                (set! loop1 (+ loop1 1))
                (set! loop2 (+ loop1 1)))
            ((< loop2 length)
                (cond ((> (list-ref list loop1) (list-ref list loop2)))
                    (set-car! temp (list-ref list loop1))
                    (list-set! list loop1 (list-ref list loop2))
                    (list-set! list loop2 temp)
                    (set-car! temp '())
                )
                (set! loop2 (+ loop2 1))
            )
        )
        (sort list length loop1 loop2 temp))
)