问题内容
一次又一次运行后,我有时会遇到这个问题。我知道这与计数器相关。当调用sync.waitgroup的done()方法的次数多于调用add()方法的次数时,它将抛出此错误。
如何解决这个问题?
我的代码创建了大小为 4 的批次,并对每个批次进行一些处理,但我在解决此恐慌时遇到了问题。
package main
import (
"fmt"
"sync"
)
func main() {
// create input channel
input := make(chan int)
// create wait group
var wg sync.waitgroup
// start batcher goroutine
wg.add(1)
go batcher(input, &wg)
// send input values to the batcher
for i := 1; i <= 10; i++ {
input <- i
}
// close input channel
close(input)
// wait for batcher goroutine to finish
wg.wait()
}
func batcher(input chan int, wg *sync.waitgroup) {
// create batch channel with buffer of size 4
batch := make(chan int, 4)
// create channel to synchronize worker goroutines
done := make(chan bool)
// create wait group for worker goroutines
var workerwg sync.waitgroup
// start worker goroutines
for i := 0; i < 4; i++ {
workerwg.add(1)
go worker(batch, &workerwg, done)
}
// read input values and send to batch
for value := range input {
batch <- value
if len(batch) == 4 {
// wait for worker goroutines to finish processing batch
workerwg.wait()
// send batch to worker goroutines
for i := 0; i < 4; i++ {
workerwg.add(1)
go sendbatch(batch, &workerwg, done)
}
}
}
// wait for worker goroutines to finish processing remaining batch
workerwg.wait()
// close done channel to notify that all batches have been processed
close(done)
wg.done()
}
func sendbatch(batch chan int, workerwg *sync.waitgroup, done chan bool) {
// process batch
for value := range batch {
fmt.println("processing value:", value)
}
// notify worker goroutines that batch has been processed
workerwg.done()
select {
case done <- true:
default:
// done channel has been closed
}
}
func worker(batch chan int, workerwg *sync.waitgroup, done chan bool) {
// process batches received from batch channel
for batch := range batch {
// process batch
fmt.println("processing batch:", batch)
workerwg.done()
}
// notify batcher goroutine that worker goroutine has finished
select {
case done <- true:
default:
// done channel has been closed
}
}
编写批处理程序的基本代码:
package main
import (
"fmt"
"sync"
)
func main() {
input := make(chan int)
output := make(chan []int)
var wg sync.waitgroup
wg.add(2)
// start the batcher goroutine
go func() {
batch := []int{}
for value := range input {
batch = append(batch, value)
if len(batch) == 4 {
output <- batch
batch = []int{}
}
}
if len(batch) > 0 {
output <- batch
}
close(output)
wg.done()
}()
// start the worker goroutine
go func() {
for batch := range output {
sum := 0
for _, value := range batch {
sum += value
}
fmt.printf("sum of batch %v: %d\n", batch, sum)
}
wg.done()
}()
// send input values to the batcher
for _, v := range []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} {
input <- v
}
close(input)
// wait for both goroutines to finish
wg.wait()
}
Sum of batch [1 2 3 4]: 10
Sum of batch [5 6 7 8]: 26
Sum of batch [9 10]: 19
早期的设计有点复杂,我会尝试扩展这个基本设计。
正确答案
根据这段代码:
for i := 0; i < 4; i++ {
workerwg.add(1)
go worker(batch, &workerwg, done)
}
我认为 workerwg.done()
应该移到循环之外:
func worker(batch chan int, workerWg *sync.WaitGroup, done chan bool) {
+ defer workerWg.Done()
// process batches received from batch channel
for batch := range batch {
// process batch
fmt.Println("Processing batch:", batch)
- workerWg.Done()
}
// notify batcher goroutine that worker goroutine has finished
select {
case done <- true:
default:
// done channel has been closed
}
}
但是batch
在demo中并没有关闭。所以事实上,goroutine 将永远运行,直到程序结束。
不知道是否还有其他问题。设计太复杂了。复杂的代码难以理解并且容易出错。考虑重新设计它。
以上就是如何解决此问题:恐慌:同步:负数 WaitGroup 计数器的详细内容,更多请关注编程网其它相关文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
软考中级精品资料免费领
- 历年真题答案解析
- 备考技巧名师总结
- 高频考点精准押题
- 资料下载
- 历年真题
193.9 KB下载数265
191.63 KB下载数245
143.91 KB下载数1148
183.71 KB下载数642
644.84 KB下载数2756
相关文章
发现更多好内容- Java 中 String 转 Long 对新手友好吗?(java string转long对新手友好吗 )
- 如何在 Java 窗口中添加文本框?(java怎么在窗口中加入文本框)
- 在 Java 中,package 究竟该如何使用呢?(java中package如何使用)
- 如何通过 JavaScript 异步编程有效避免回调地狱?(JavaScript异步编程如何避免回调地狱)
- 在 JavaScript 中,split 方法究竟该如何使用?(split方法在javascript中怎么用)
- 如何解决 java log4j2 的安全漏洞?(java log4j2安全漏洞解决方案)
- 如何在 Java 中对幂函数的性能进行优化?(如何在Java中优化幂函数的性能)
- 如何编写 Java 获取文件行数的代码?(Java获取文件行数的代码怎么写)
- Java 中 == 和 equals 的区别究竟有哪些?(java中==和equals的区别是什么)
- Java 如何读取外部配置文件?(详细教程及 SEO 优化指南)(java怎么读取外部配置文件)
猜你喜欢
AI推送时光机如何解决此问题:恐慌:同步:负数 WaitGroup 计数器
后端开发2024-02-05
Go语言中的数组同步问题如何解决?
后端开发2023-10-09
Python path 设置正确了吗?如何解决大数据同步问题?
后端开发2023-10-12
numpy和ASP:如何解决数据类型同步所带来的性能问题?
后端开发2023-10-30
如何使用同步函数解决Java自然语言处理中的并发问题?
后端开发2023-10-29
咦!没有更多了?去看看其它编程学习网 内容吧