panjf2000 / gnet

🚀 gnet is a high-performance, lightweight, non-blocking, event-driven networking framework written in pure Go.
https://gnet.host
Apache License 2.0
9.7k stars 1.04k forks source link

[Bug]: 产生数据竞争 #486

Closed yongjuntang closed 1 year ago

yongjuntang commented 1 year ago

Actions I've taken before I'm here

What happened?

当在两个goroutine里调用gnet.Run()时,gnet.Run()函数内的logger产生数据竞争. 因为我需要在一个程序里用两个端口提供各自不同的服务,所以启用了两个gnet服务,产生上述问题。

Major version of gnet

v2

Specific version of gnet

v2.3.0

Operating system

macOS

OS version

Darwin 22.3.0 x86_64

Go version

go1.20

Relevant log output

WARNING: DATA RACE
Read at 0x0000029276f8 by goroutine 65:
  github.com/panjf2000/gnet/v2.Run()
      /Users/xx/go/pkg/mod/github.com/panjf2000/gnet/v2@v2.3.0/gnet.go:438 +0x10e
  bb/baseServices/servers/gameserver.(*GameServerBaseService).Init.func1()

Previous write at 0x0000029276f8 by goroutine 66:
  github.com/panjf2000/gnet/v2/pkg/logging.SetDefaultLoggerAndFlusher.func1()
      /Users/xx/go/pkg/mod/github.com/panjf2000/gnet/v2@v2.3.0/pkg/logging/logger.go:191 +0x88
  sync.(*Once).doSlow()
      /usr/local/go/src/sync/once.go:74 +0x101
  sync.(*Once).Do()
      /usr/local/go/src/sync/once.go:65 +0x46
  github.com/panjf2000/gnet/v2/pkg/logging.SetDefaultLoggerAndFlusher()
      /Users/xx/go/pkg/mod/github.com/panjf2000/gnet/v2@v2.3.0/pkg/logging/logger.go:190 +0x84
  github.com/panjf2000/gnet/v2.Run()
      /Users/xx/go/pkg/mod/github.com/panjf2000/gnet/v2@v2.3.0/gnet.go:448 +0x290
  bb/baseServices/servers/chatserver.(*ChatServerBaseService).Init.func1()
      /Users/xx/vscode/bb/baseServices/servers/chatserver/service.go:44 +0x584

Code snippets (optional)

go func() {

        err := gnet.Run(cServer, cServer.addr, options...)
        if err != nil {
            log.Errorf("gnet.Run() erro:%v", err)
            os.Exit(1)
        }
    }()

        go func() {

        err := gnet.Run(gServer, gServer.addr, options...)
        if err != nil {
            log.Errorf("gnet.Run() erro:%v", err)
            os.Exit(1)
        }
    }()

How to Reproduce

1.将gnet.Run()放在两个goroutine中 2.每个gnet.Run监听不同的端口 3.启动程序

  1. go run -race main.go 产生竞争输出

Does this issue reproduce with the latest release?

It can reproduce with the latest release