【发布时间】:2018-06-25 19:26:37
【问题描述】:
我有一个包含数千个 ID 的通道,需要在 goroutine 中并行处理。如何实现一个锁,让 goroutines 不能同时处理相同的 id,是否应该在通道中重复?
package main
import (
"fmt"
"sync"
"strconv"
"time"
)
var wg sync.WaitGroup
func main() {
var data []string
for d := 0; d < 30; d++ {
data = append(data, "id1")
data = append(data, "id2")
data = append(data, "id3")
}
chanData := createChan(data)
for i := 0; i < 10; i++ {
wg.Add(1)
process(chanData, i)
}
wg.Wait()
}
func createChan(data []string) <-chan string {
var out = make(chan string)
go func() {
for _, val := range data {
out <- val
}
close(out)
}()
return out
}
func process(ids <-chan string, i int) {
go func() {
defer wg.Done()
for id := range ids {
fmt.Println(id + " (goroutine " + strconv.Itoa(i) + ")")
time.Sleep(1 * time.Second)
}
}()
}
--编辑: 所有值都需要按任意顺序处理,但“id1,”id2”和“id3”需要阻塞,因此它们不能被多个goroutine同时处理。
【问题讨论】:
-
最简单的大概是创建一个全局的
map[yourIDType]*sync.Mutex。 -
为什么不去重复数据之前同时访问它。无论如何,您都需要序列化访问,那么为什么要阻止所有相当于地图查找的内容呢?
-
谢谢阿德里安,我不相信你能做到这一点,因为地图不是线程安全的,并发访问时会恐慌。
标签: go