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

fatal error: concurrent map writes #456

Closed 514366607 closed 1 year ago

514366607 commented 1 year ago
fatal error: concurrent map writes

goroutine 69235 [running]:
github.com/panjf2000/gnet/v2.(*eventloop).closeConn(0xc00019c630, 0xc0004c6a20, {0x1f81820, 0xc0005a33c0})
    /Users/hible/go/pkg/mod/github.com/panjf2000/gnet/v2@v2.2.6/eventloop.go:224 +0x33f
github.com/panjf2000/gnet/v2.(*conn).write(0xc0004c6a20, {0xc0008be500, 0x4f4, 0x4f4})
    /Users/hible/go/pkg/mod/github.com/panjf2000/gnet/v2@v2.2.6/connection.go:147 +0x147
github.com/panjf2000/gnet/v2.(*conn).Write(0x1f79960?, {0xc0008be500?, 0x0?, 0xc001332e10?})
    /Users/hible/go/pkg/mod/github.com/panjf2000/gnet/v2@v2.2.6/connection.go:351 +0x5b
192.168.0.11/wjtamriel/tamriel-go/service/gate/client.(*Client).Write(0xc000eaa1e0, 0x1d4d8e0?)
    /Users/hible/Documents/GitHub/tamriel-go/service/gate/client/struct_unix.go:82 +0xc9
192.168.0.11/wjtamriel/tamriel-go/service/gate/client.(*Client).roleServiceRecv(0x10f9a6a?, 0xc000ffafc0?)
    /Users/hible/Documents/GitHub/tamriel-go/service/gate/client/stream.go:110 +0x74
192.168.0.11/go-extend/engine/stream.(*GRPCStreamClient).loopRecv(0xc000201900)
    /Users/hible/go/pkg/mod/192.168.0.11/go-extend/engine@v0.12.7/stream/client.go:143 +0xd1
created by 192.168.0.11/go-extend/engine/stream.(*GRPCStreamClient).Connect
    /Users/hible/go/pkg/mod/192.168.0.11/go-extend/engine@v0.12.7/stream/client.go:93 +0x17e

name: Pull request about: Propose changes to the code title: '' labels: '' assignees: ''

1. Are you opening this pull request for bug-fixes, optimizations or new feature?

bug-fixes

2. Please describe how these code changes achieve your intention.

使用协程安全的sync.Map来存放全局变量。

3. Please link to the relevant issues (if any).

4. Which documentation changes (if any) need to be made/updated because of this PR?

4. Checklist

514366607 commented 1 year ago

高并发情况下,操作map会导致进程直接关闭。

panjf2000 commented 1 year ago

gnet 的内部设计是无锁的,通过确保每个 eventloop 的内部资源只能由其所属的单一 goroutine 访问,你是不是在 eventloop 的 goroutine 之外调用了非并发安全的方法?

514366607 commented 1 year ago

gnet 的内部设计是无锁的,通过确保每个 eventloop 的内部资源只能由其所属的单一 goroutine 访问,你是不是在 eventloop 的 goroutine 之外调用了非并发安全的方法?

这两个函数在 不同的goroutine 同时调用就可能同时调用到c.loop.closeConn() (c conn) Close() (c conn) Write()

我的出现的场景是 角色连接网关后在监听角色服务的推送通知。

在网关连接断开,且收到角色服务的通知,这时候就会要通知给玩家。

就会同时调用 close和write,出现同时操作map的情况

panjf2000 commented 1 year ago

如果是在 eventloop 所在的 goroutine 之内就使用非并发安全的方法,如果在在 eventloop 所在的 goroutine 之外则需要使用并发安全的方法

514366607 commented 1 year ago

哦,原来是我的使用方式不对,我看到相关代码了,thx。