我有一个go-routine
将对象添加到通道中,然后我有四个go- routines
要处理通道的对象。处理不过是将对象添加到数组而已。但是有时,最终数组中缺少对象。因此,我假设某个时候通道停止收集对象。我有以下代码:
package main
import (
"log"
"sync"
)
func main() {
j := 0
for {
if j == 10 {
break
}
wg := sync.WaitGroup{}
months := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"}
hits := make(chan string)
i := 0
wg.Add(1)
go func() {
defer close(hits)
for {
if i == 25 {
wg.Done()
return
}
for _, month := range months {
hits <- month
}
i++
}
}()
temp := []string{}
for updateWorker := 1; updateWorker <= 4; updateWorker++ {
wg.Add(1)
go func() {
for hit := range hits {
temp = append(temp, hit)
}
wg.Done()
return
}()
}
wg.Wait()
log.Printf("length of temp %+v\n", len(temp))
j++
}
}
我正在使用sync
库来同步例程。我将同一进程循环10次以测试输出是否一致。我期望这样的输出:
length of temp 175
是175,因为我发送了7个月的字符串25次。但是有时输出少于175,我不知道为什么。我对围棋例程有点初学者。那么有人可以在这里帮助我找到原因吗?谢谢。
问题在于,updateWorker
goroutine都从hits
通道收集了结果(到目前为止很好),并且它们都将结果存储在未 同步*
的temp
本地变量中。这不行。
*
必须同步访问多个goroutine中的所有变量(其中至少有一个是写操作)。
如果在启用了竞争检测器的情况下运行它,它会发出有关数据竞争的尖叫(go run -race app.go
)。
如果将updateWorker
goroutine 的数量减少到1,它将立即产生有效的结果,因为这样我们就消除了应用程序的单个数据争用源:
for updateWorker := 1; updateWorker <= 1; updateWorker++ {
// ...
}
如果要保留多个updateWorker
goroutine,则temp
必须同步它们对共享变量的访问。
带有sync.Mutex
:
var (
mu sync.Mutex
temp []string
)
for updateWorker := 1; updateWorker <= 4; updateWorker++ {
wg.Add(1)
go func() {
for hit := range hits {
mu.Lock()
temp = append(temp, hit)
mu.Unlock()
}
wg.Done()
return
}()
}
还要注意,在这个简单的示例中,通过使用多个updateWorker
goroutine并不会获得任何好处,与仅使用其中的一个相比,添加上述同步(锁定)甚至会使性能降低。
我的Eclipse中有一个运行在Windows 10上的MavenJava项目。该项目构建良好,并在目标文件夹中生成m-m.jar文件。 如何要求Maven收集所有需要运行这个项目的jar? 波姆。xml内容:
我正在尝试使用 Jolt 转换来转换 JSON,在这里寻找一些输入。我正在尝试将所有级别中的所有项目放入一个数组中。 我的目标是获得一个包含所有项目的数组,而不知道我在json中有多少个级别。 这是我的输入和预期输出: 如果我有三个等级: 输入: 预期产出: 如果我有两个级别: 输入: 预期产出: 我试着写下这样的话: 结果为空,如果我单独运行每个转换,我会在适用时得到结果。你能帮我写一个简单的规
我们正在考虑将flyway集成到我们的系统中,因为它似乎是以有效方式管理数据库迁移的绝佳工具。 然而,我不太确定如何继续: 我们有三个不同的数据库 < li >生产环境(MySQL) < li >测试环境(MySQL) < li >单元测试(H2内存中) 它们都包含不同的数据(不同的用户等)。数据库之间没有公共数据(在飞行路线页面上,这称为参考数据),只有结构应该保持不变。 看着网站,我的理解是这
根据这个问题的答案,在第11行没有符合GC条件的对象;但是根据我的说法,至少有一个对象t2,它在第6行被设置为指向null,应该有资格进行垃圾回收。
问题内容: 是否有一种(非破坏性的)方式列出缓冲通道中的所有元素? 我唯一能想到的就是循环所有这些,最后将它们重新插入。这似乎不是最聪明的方法。 链接到游乐场 问题答案: 从2011年开始,该线程在通道周围提供了一些包装程序,以启用Peek()函数,但这比其他任何方法都更可行。 总的结论是: 同步通道没有头(就像零长度切片) 你不能那样做,因为 a)它被放回队列的尾部而不是末端,并且 b)作家可能
我正在尝试使用 Jolt 转换来转换 JSON,在这里寻找一些输入。我正在尝试将所有级别中的所有项目放入一个数组中。我的目标是获得一个包含所有项目的数组,而不知道我在 json 中有多少个级别。 这是我的输入和预期输出: 输入: 预期产出: 我的震动规格: 结果: 只有前4项包含id和foo,但并不是它们的foo值都只有一个。 你能告诉我怎么做对吗?