为了账号安全,请及时绑定邮箱和手机立即绑定

http handlefunc 上的 Golang 地图更新

http handlefunc 上的 Golang 地图更新

Go
LEATH 2022-11-23 20:38:18

我有一个关于 map 语言的问题。我想处理客户端 ( ) 并使用(key (client IP) value pair) http保存他们的一些信息...使用新线程处理每个 http 客户端,所以我认为更改(添加、删除、编辑)数据将不安全……我的行为安全吗?maphttpmap


package main


import (

    "net/http"

)


func main() {

    var clientsData map[string]string

    http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {

        // Is this map adding, safe or i have to use thread lock (mutex or ...) ?

        clientsData[request.RemoteAddr] = ...

    })

    http.ListenAndServe("127.0.0.10:8090", nil)

}


查看完整描述

2 回答

?
子衿沉夜

TA贡献1553条经验 获得超3个赞

简单地使用https://eli.thegreenplace.net/2019/on-concurrency-in-go-http-servers/中的示例可以构建一个简单的示例,表明它并不安全。


使用一个简单的程序,如:


package main


import (

    "net/http"

)


func main() {

    counters := map[string]int{}

    name := "test"

    counters[name] = 0

    http.HandleFunc("/test", func(w http.ResponseWriter, req *http.Request) {

        counters[name]++

    })


    http.ListenAndServe(":8000", nil)

}

并刺激使用:


ab -n 20000 -c 200 "127.0.0.1:8000/test"

产生异常,如:


goroutine 158 [running]:

runtime.throw({0x64d95a, 0x81faa0})

        /usr/local/go/src/runtime/panic.go:1198 +0x71 fp=0xc000384980 sp=0xc000384950 pc=0x4348f1

runtime.mapaccess2_faststr(0x697360, 0xc0003a4ba0, {0x644851, 0x4})

        /usr/local/go/src/runtime/map_faststr.go:116 +0x3d4 fp=0xc0003849e8 sp=0xc000384980 pc=0x413d34

main.main.func1({0x69bf00, 0xc0003a4b60}, 0x0)

        /home/test/gohttp/main.go:13 +0x46 fp=0xc000384a48 sp=0xc0003849e8 pc=0x5eba86

net/http.HandlerFunc.ServeHTTP(0x0, {0x69bf00, 0xc0003a4b60}, 0x0)


查看完整回答
反对 回复 5天前
?
www说

TA贡献1490条经验 获得超8个赞

如果您只阅读,那是安全的。

如果你需要写,你需要一些方法来做到“线程安全”

第一个想法是使用 sync.Mutex 来保护对地图的访问

然而,这可能成为瓶颈,因为您可能有多个并行请求,但每次只能写入一个。我们谈论的是纳秒……

第二种方法可以使用读/写互斥锁来控制读写。许多 goroutines 可以读取,但每次只有一个可以写入。

包同步和同步/原子还有其他选项。

还有一种额外的方法需要考虑:如果你只需要写入这个地图,你可以考虑使用缓冲通道发送一个键/值结构,以便在单个 goroutine 中使用(负责将它存储到地图中)

如您所见,如果对您的应用程序有意义,这种方法有很多优点。

您甚至可以使用通道通过回调来安全读/写,但这是另一回事了。

如果您有疑问,请编写单元测试并使用竞争条件检测器


查看完整回答
反对 回复 5天前

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信