记使用WaitGroup时的一个错误

记使用WaitGroup时的一个错误

近期重构我之前写的server代码时,不当使用了WaitGroup,碰到了个错误,记录下.

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup
    wg.Add(1)

    f1 := func() {
        time.Sleep(time.Second * 2)
        fmt.Println("func()")
        wg.Done()
    }

    go f1()
    go f1()
    go f1()

    wg.Wait()
    fmt.Println("Done")
}

/*
D:\test\>go run testwg2.go
func()
func()
panic: sync: negative WaitGroup counter

goroutine 22 [running]:
runtime.panic(0x4a56e0, 0xc082000250)
        c:/go/src/pkg/runtime/panic.c:279 +0x11f
sync.(*WaitGroup).Add(0xc0820045e0, 0xffffffffffffffff)
        c:/go/src/pkg/sync/waitgroup.go:64 +0x9a
sync.(*WaitGroup).Done(0xc0820045e0)
        c:/go/src/pkg/sync/waitgroup.go:82 +0x37
main.func路001()
        D:/test/testwg2.go:17 +0xd2
created by main.main
        D:/test/testwg2.go:22 +0x9a

*/

出现的错误: panic: sync: negative WaitGroup counter
关于这个错误, stackoverflow有个相关问题的链接.

还有一个错误:

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {

    var wg sync.WaitGroup
    wg.Add(10)

    f1 := func() {
        time.Sleep(time.Second * 2)
        fmt.Println("func()")
        wg.Done()
    }

    go f1()
    go f1()
    go f1()

    wg.Wait()
    fmt.Println("Done")
}

/*

D:\test\>go run testwg2.go
func()
func()
func()
fatal error: all goroutines are asleep - deadlock!

goroutine 16 [semacquire]:
sync.runtime_Semacquire(0xc0820001bc)
        c:/go/src/pkg/runtime/sema.goc:199 +0x37
sync.(*WaitGroup).Wait(0xc0820045e0)
        c:/go/src/pkg/sync/waitgroup.go:129 +0x152
main.main()
        D:/test/testwg2.go:24 +0xaa

goroutine 19 [finalizer wait]:
runtime.park(0x414db0, 0x55ec80, 0x55d689)
        c:/go/src/pkg/runtime/proc.c:1369 +0xac
runtime.parkunlock(0x55ec80, 0x55d689)
        c:/go/src/pkg/runtime/proc.c:1385 +0x42
runfinq()
        c:/go/src/pkg/runtime/mgc0.c:2644 +0xdd
runtime.goexit()
        c:/go/src/pkg/runtime/proc.c:1445
exit status 2

*/

事实上这些错误主要是当时wg的add与done由于一些原因分开处理了。


中间由于穿插了一大堆处理。一直done造成wg负数了,如例1,或者add
与done造成了deadlock。


以后实际处理中要注意下。尽量降低中间处理。把这样的需相应的简洁化处理.

只是近期重构server蛮爽的。经过大遍大遍的清理代码,梳理流程后。


代码看着顺眼了非常多。

只是还是任重而道远。

BLOG: blog.csdn.net/xcl168

posted @ 2017-07-18 13:00  wzzkaifa  阅读(2592)  评论(0编辑  收藏  举报