Golang Go语言中发起HTTP请求时,设置header头的操作是线程安全的吗?

发布于 1周前 作者 phonegap100 来自 Go语言

有如下代码:
req, _ := http.NewRequest(“POST”, “http://example.com”, nil)
req.Header.Set(“Content-Type”, “application/json”)
追了一下 golang 源码 header 是 map[string][]string 类型,
set 方法的源码是:
func (h Header) Set(key, value string) {
textproto.MIMEHeader(h).Set(key, value)
}
看上去,在做 header set 的时候,golang 并没有做加锁解锁等操作。
我还去看了下 resty 请求库和 gorequest 请求库,发现实现方式和 go 原生的是一样的。

我的需求:要并发发起 http post 请求,每个请求需要设置不同的 auth header 头
我的疑问:
1 、在设置 header 的时候是否存在 map 并发读写的问题?
2 、在并发发起 http post 请求的时候,request 是共用一个,还是每次发起都 new 一个?
Golang Go语言中发起HTTP请求时,设置header头的操作是线程安全的吗?


更多关于Golang Go语言中发起HTTP请求时,设置header头的操作是线程安全的吗?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

request 显然是每次都 new 一个

更多关于Golang Go语言中发起HTTP请求时,设置header头的操作是线程安全的吗?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


  1. 存在
    2. 可以 new 一个模版然后 Clone

都是 new 一个新的

同意一楼, 看你代码实现是 new 一个 request 后通过多个 goroutine 修改这个 request 来实现多个请求并发,还是每个请求都 new 一个 request , 后者每个 request 都是独立的所以并不会出现并发问题,前者的话不建议你这么做。

在设计上就不是让你共享 request 的,那不是正确的使用方式。每次请求就是一个独立的 request 。

你这本身就是个骚操作,设计上不考虑这种情况,所以。

这不应该直接看下源码吗…

凭我的印象 http.Client Do 里面最初就直接 copy headers 了,也就是在这一步之间进行修改的话确实会 panic

你不会开多线程拼 header 吧[狗头]

在Golang(Go语言)中,发起HTTP请求时设置header头的操作是线程安全的。这得益于Go语言标准库中对并发编程的深入考虑和优化,以及HTTP客户端库(net/http)的精心设计。

在Go的net/http包中,HTTP请求和响应对象(http.Requesthttp.Response)是值类型(value types),这意味着它们在被复制时会生成一个新的实例,而这些实例之间不会共享内部状态。当你设置HTTP请求的header头时,实际上是在操作这个请求对象的一个字段,这个字段是一个map,而Go语言中的map在并发读写时默认不是线程安全的。但在HTTP客户端的使用场景中,每个请求对象通常是在一个单独的goroutine中创建和修改的,因此不会存在多个goroutine并发修改同一个请求对象的情况。

此外,即使你在多个goroutine中操作不同的http.Request对象,由于它们是独立的实例,所以也不会相互影响。

总的来说,在标准的HTTP客户端使用场景下,设置HTTP请求的header头是线程安全的。但如果你需要在并发环境下共享和修改同一个http.Request对象,那么你需要自己采取同步措施来保证线程安全。不过,在大多数情况下,这是不必要的,因为每个HTTP请求都应该是独立和自包含的。

回到顶部