- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我已经实现了这个 answer 中提到的 goroutine 的生产者-消费者模式.但它有时会出现 panic ,并出现错误提示:“ panic :同步:负 WaitGroup 计数器”。我有如下示例代码:
package main
import (
"bytes"
"encoding/gob"
"log"
_ "net/http/pprof"
"sync"
)
// Test ...
type Test struct {
PropA []int
PropB []int
}
// Clone deep-copies a to b
func Clone(a, b interface{}) {
buff := new(bytes.Buffer)
enc := gob.NewEncoder(buff)
dec := gob.NewDecoder(buff)
enc.Encode(a)
dec.Decode(b)
}
func main() {
test := Test{
PropA: []int{211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222},
PropB: []int{111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124},
}
var wg, wg2 sync.WaitGroup
ch := make(chan int, 5)
results := make(chan Test, 5)
// start consumers
for i := 0; i < 4; i++ {
wg.Add(1)
go func(ch <-chan int, results chan<- Test) {
defer wg.Done()
for propA := range ch {
var temp Test
Clone(&test, &temp)
temp.PropA = []int{propA}
results <- temp
}
}(ch, results)
}
// start producing
go func(ch chan<- int) {
defer wg.Done()
for _, propA := range test.PropA {
ch <- propA
}
close(ch)
}(ch)
wg2.Add(1)
go func(results <-chan Test) {
defer wg2.Done()
for tt := range results {
log.Printf("finished propA %+v\n", tt.PropA[0])
}
}(results)
wg.Wait() // Wait all consumers to finish processing jobs
// All jobs are processed, no more values will be sent on results:
close(results)
wg2.Wait()
}
当我运行上述代码 4-5 次时,它至少会出现一次 panic 。有时,错误消息是“ panic :在关闭的 channel 上发送”。我不明白在生产者完成发送之前 channel 是如何关闭的,以及为什么 Waitgroup 计数器达到负值。有人可以解释一下吗?
编辑panic 的堆栈跟踪如下:(以上代码的文件名是 mycode.go
)
panic: send on closed channel
panic: sync: negative WaitGroup counter
goroutine 21 [running]:
sync.(*WaitGroup).Add(0xc420134020, 0xffffffffffffffff)
/usr/local/go/src/sync/waitgroup.go:75 +0x134
sync.(*WaitGroup).Done(0xc420134020)
/usr/local/go/src/sync/waitgroup.go:100 +0x34
panic(0x7622e0, 0x80ffa0)
/usr/local/go/src/runtime/panic.go:491 +0x283
main.main.func1(0xc420134020, 0xc420136090, 0xc420148000, 0xc42014a000)
/home/mycode.go:45 +0x80
created by main.main
/home/mycode.go:39 +0x21d
exit status 2
最佳答案
您在 wg
上的记账差了一个,因为您的制作人调用了 wg.Done()
但没有调用 Add()
占它。 panic 与 go 调度程序的可变性有关,但一旦你看到修复,我相信你会看到如何根据时间获得“负 WaitGroup 计数器”和/或“在关闭的 channel 上发送”。
修复很简单,只需在启动生产者之前添加一个 wg.Add()
。
...
wg.Add(1)
// start producing
go func(ch chan<- int) {
defer wg.Done()
for _, propA := range test.PropA {
ch <- propA
}
close(ch)
}(ch)
...
将来,当您看到“负的 WaitGroup 计数器”时,可以保证您不会将 Add
的数量与 Done
的数量进行 1:1 匹配。
关于去例行的生产者消费者模式 panic ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47218844/
在Go(go1.2.1 linux/amd64)中运行http服务器时,我遇到了一个罕见的错误。 unexpected fault address 0xb84004 fatal error: faul
使用以下代码: var i interface{} = "hello" f, ok := i.(float64) fmt.Println(f, ok) f = i.(float64) // panic
考虑以下故意导致双重 panic 的代码: use scopeguard::defer; // 1.1.0 fn main() { defer!{ panic!() }; defer!
如果我传递给 std::panic::set_hook 的函数发生 panic 会怎样? 我可以想象对此做出多种 react :考虑这个 UB,中止程序 like C++ does ,为新的 pani
我有一个 string,当我想获取 i 索引处的值时它会崩溃,但是当我切出相同的 string 保持较低的索引值作为长度然后它不会 panic 。想知道 1 和 2 有何不同? func main()
看起来不可能从 panic 中的 panic 中恢复过来? func TestError(t *testing.T) { e := &myErr{p: false} fmt.Print
当我使用 cargo test 运行以下程序时: use std::panic; fn assert_panic_func(f: fn() -> (), msg: String) { let
在开发过程中,我遇到了崩溃,并显示了内核 panic 上传模式。 有没有办法以某种方式连接到设备并提取日志? 最佳答案 我希望这就是您正在寻找的...来源:StackOverflowAndroid 创
我需要制造内核 panic ,我尝试了以下操作 sysctl kernel.panic=0 && echo c > /proc/sysrq-trigger 当我运行上面的命令时。我看到系统总是重新启动
是否可以从 recover 中“重新抛出”错误并保留原始堆栈跟踪?我知道的最好的办法就是再次 panic ,但这确实会创建一个新的堆栈跟踪。 func do() { defer func()
我正在使用 panic::catch_unwind引起 panic : use std::panic; fn main() { let result = panic::catch_unwind
func sub(){ defer func (){ panic(2) }() panic(1) } func main(){ defer func()
考虑到我使用的是原始的“errors”go 包。 还有,panic(11) 和 panic("11") 之间的区别? 最佳答案 panic定义为 func panic(v interface{}),调
我是 golang 的新手。在定义位置后 try catch 主 block 中的错误后,我的程序出现 panic 。我在某处读过,添加 defer.close() 可能会有所帮助,但编译器再次说你的
有这种新的编程语言 V-lang由亚历克斯·梅德维尼科夫 (Alex Medvednikov) 创建。我目前使用的是 V-lang 0.1.11 版。我可以在 V-lang 中声明一个数组,如下所示:
在启动 linux 时,我在控制台上得到以下打印,并且系统挂起。 Waiting for root device /dev/mmcblk0p2... mmc_host mmc0: Bus speed
我已经实现了这个 answer 中提到的 goroutine 的生产者-消费者模式.但它有时会出现 panic ,并出现错误提示:“ panic :同步:负 WaitGroup 计数器”。我有如下示例
上下文: https://github.com/fusspawn/tserver/blob/master/app/controllers/gorp.go 作为尝试设置 gorm 的一部分,我尝试转换标
专注Golang,Python语言,云原生,人工智能领域得博主 过去经历的意义在于引导你,而非定义你, 只要我们足够努力,任何人都有无限潜力 panic 抛出异常函数 recove
这个问题在这里已经有了答案: How to return a value in a Go function that panics? (3 个回答) 2年前关闭。 package main impor
我是一名优秀的程序员,十分优秀!