我在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时,相同的代码工作正常。
我是否遗漏了某些内容,或者切片不是线程安全的,并且被分配了相同的变量。
答案 0 :(得分:2)
在Go string
中是不可变的,所以它工作正常,但所有切片都是可变的。此外,他们可以共享后备阵列。您没有显示相关代码,但我猜您希望地图能够保存切片的副本。 slice只是内存和长度的地址。您需要手动创建一个新切片并复制其内容。
要修复代码,请在将其放入地图时制作切片的副本。