使用golang通道时出现分段错误

4
以下代码开启了10000个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)
    }
}

4
始终,检查错误。 - JimB
2个回答

6

在调用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)
    }
}

3
这个错误通常是由于尝试引用不存在或尚未创建的对象所致。
在上面的代码中,如果你尝试在 body 不存在时调用 resp.Body.Close(),那么就会出现空指针引用错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接