通过通道的Golang字节数组通信丢失数据

时间:2017-03-30 07:57:04

标签: arrays go channel goroutine

我在golang项目中使用了work-worker队列实现。 WorkRequest Struct如下所示

type WorkRequest struct {
fields map[string] []byte }

和dipatcher是

go func() {
    for {
        select {
        case work := <-WorkQueue:
            go func() {
                worker := <-WorkerQueue
                worker.Work <- work
            }()
        }
    }
}()

worker.Work是WorkRequest结构的通道,而WorkerQueue是Worker结构的通道。 每当WorkQueue中有许多并发请求时,就会通过调度程序将其分配给worker。

当我向WorkQueue发送并发请求时,我正在观察问题,很少有人错过了,很少有人多次执行。

e.g。如果我排队使用ID 1,2,3,4,5 ...那么我看到工作人员使用ID 1,2,4,4,5 ...这里4执行两次,3错过。当我将WorkRequest字段实现为map [string]字符串而不是[] byte时,相同的代码工作正常。

我是否遗漏了某些内容,或者切片不是线程安全的,并且被分配了相同的变量。

1 个答案:

答案 0 :(得分:2)

在Go string中是不可变的,所以它工作正常,但所有切片都是可变的。此外,他们可以共享后备阵列。您没有显示相关代码,但我猜您希望地图能够保存切片的副本。 slice只是内存和长度的地址。您需要手动创建一个新切片并复制其内容。

要修复代码,请在将其放入地图时制作切片的副本。