golang 通道的分段违规
Segmentation violation with golang channels
下面的代码打开了 10,000 个 go 例程,这些例程进行 HTTP 调用、获取响应、关闭响应并写入具有 ID 的通道。
在第二个 for 循环中,它从缓冲通道打印出前一个 go 例程的 ID。
这会导致分段冲突,我不明白为什么。
恐慌:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x2293]
代码:
package main
import (
"fmt"
"net/http"
)
func main() {
requests := 10000
ch := make(chan string, requests)
for i := 1; i <= requests; i++ {
go func(iter int) {
fmt.Println(iter)
resp, _ := http.Get("http://localhost:8080/api/project")
resp.Body.Close()
ch <- fmt.Sprint("%i", iter)
}(i)
}
for i := 1; i <= requests; i++ {
fmt.Println(<-ch)
}
}
调用 api 时不检查任何错误。因此,在尝试关闭从未到达的响应时出现错误。
这段代码不会乱码:
package main
import (
"fmt"
"net/http"
)
func main() {
requests := 10000
ch := make(chan string, requests)
for i := 1; i <= requests; i++ {
go func(iter int) {
fmt.Println(iter)
resp, err := http.Get("http://localhost:8080/api/project")
if (err == nil) {
resp.Body.Close()
}
ch <- fmt.Sprint(iter)
}(i)
}
for i := 1; i <= requests; i++ {
fmt.Println(<-ch)
}
}
此错误的一般原因是当您尝试引用不存在或尚未创建的对象时。
在上面的代码中,如果您在 body
不存在时尝试调用 resp.Body.Close()
,那将变成一个空指针引用,因此会出现错误。
下面的代码打开了 10,000 个 go 例程,这些例程进行 HTTP 调用、获取响应、关闭响应并写入具有 ID 的通道。
在第二个 for 循环中,它从缓冲通道打印出前一个 go 例程的 ID。
这会导致分段冲突,我不明白为什么。
恐慌:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x2293]
代码:
package main
import (
"fmt"
"net/http"
)
func main() {
requests := 10000
ch := make(chan string, requests)
for i := 1; i <= requests; i++ {
go func(iter int) {
fmt.Println(iter)
resp, _ := http.Get("http://localhost:8080/api/project")
resp.Body.Close()
ch <- fmt.Sprint("%i", iter)
}(i)
}
for i := 1; i <= requests; i++ {
fmt.Println(<-ch)
}
}
调用 api 时不检查任何错误。因此,在尝试关闭从未到达的响应时出现错误。
这段代码不会乱码:
package main
import (
"fmt"
"net/http"
)
func main() {
requests := 10000
ch := make(chan string, requests)
for i := 1; i <= requests; i++ {
go func(iter int) {
fmt.Println(iter)
resp, err := http.Get("http://localhost:8080/api/project")
if (err == nil) {
resp.Body.Close()
}
ch <- fmt.Sprint(iter)
}(i)
}
for i := 1; i <= requests; i++ {
fmt.Println(<-ch)
}
}
此错误的一般原因是当您尝试引用不存在或尚未创建的对象时。
在上面的代码中,如果您在 body
不存在时尝试调用 resp.Body.Close()
,那将变成一个空指针引用,因此会出现错误。