Io 同时写入和读取数组的最惯用方法

Io 同时写入和读取数组的最惯用方法,io,go,goroutine,Io,Go,Goroutine,我有一个数组,用一个goroutine每秒修改几次。在另一个函数中,我每隔几秒钟从数组中读取一个随机值。解决这个问题最有效的方法是什么 例如,在Java中,我会先锁定数组,然后从中读取。我不确定是否可以为此使用通道,因为我不想等到其他函数读取后才能继续更新阵列 package main import ( "fmt" "math/rand" "time" ) const ( SliceLength = 32 ) var mySlice []int func

我有一个数组,用一个goroutine每秒修改几次。在另一个函数中,我每隔几秒钟从数组中读取一个随机值。解决这个问题最有效的方法是什么

例如,在Java中,我会先锁定数组,然后从中读取。我不确定是否可以为此使用通道,因为我不想等到其他函数读取后才能继续更新阵列

package main

import (
    "fmt"
    "math/rand"
    "time"
)

const (
    SliceLength = 32
)

var mySlice []int

func randInt(min int, max int) int {
    return min + rand.Intn(max-min)
}

func writeSlice() {
    for index, _ := range mySlice {
        mySlice[index] = rand.Intn(100)
    }
}

func main() {
    rand.Seed(time.Now().UnixNano())
    mySlice = make([]int, SliceLength)

    // First time just to populate it.
    writeSlice()

    // Write to the slice.
    go func() {
        for {
            time.Sleep(time.Duration(randInt(10, 50)) * time.Millisecond)
            writeSlice()
        }
    }()

    // Read from slice.
    for {
        time.Sleep(time.Duration(randInt(1, 5)) * time.Second)
        fmt.Println(mySlice[randInt(0, SliceLength)])
    }
}
听起来像是一份适合你的工作

RWMutex是读写器互斥锁。锁可以由任意数量的读卡器或单个写入器持有。rwMutex可以作为其他结构的一部分创建;RWMutex的零值是未锁定的mutex

互斥可以在这里工作。您只需在两个goroutine之间共享切片,在每个切片操作之前/之后锁定和释放

当你探索可能性的时候,你也应该考虑什么是“<强> <强”原则。您可能希望找到一个不使用互斥锁的解决方案,其中每个goroutine都只有私有数据—不共享任何内容

假设你有第三个goroutine。把它想象成一个服务器。它保存切片(或任何其他需要争用的数据结构)。当您的第一个goroutine想要进行更改时,它会通过一个通道向服务器发送一条消息,说“将x更改为y”。当您的第二个goroutine想要读取数据时,它可能只是从服务器的通道中读取数据的副本

在服务器内部,select语句将在传入的更新消息和传出的读取消息之间进行选择—请记住,保护可以位于通道输入或通道输出上,因此这很容易做到

...  declare and initialise the slice
for {
    select {
    case instruction = <-update:
        ...  apply the instruction to the slice
    case output<- slice:
        ...  sent the slice to the consumer
    }
}
。。。声明并初始化切片
为了{
挑选{

case instruction=如果我使用RWMutex,我将如何调用它?
mutex:=sync.RWMutex
,然后只
mutex.Lock()
,写入片,然后
mutex.Unlock()
?它如何知道锁定我的片?还有,
sync.mutex
sync.RWMutex
之间的区别是什么?