通过 Go HTTP 导入避免死锁错误
在 Go 中,使用 net/http 包进行 HTTP 通信引入了一种微妙的行为,可能会影响死锁检测。
考虑以下代码:
<code class="go">package main import ( "fmt" "net/http" ) func Extract(url string) ([]string, error) { http.Get(url) var links []string return links, nil } func crawl(url string) []string { list, _ := Extract(url) return list } func main() { var ch = make(chan int) ch <- 1 }</code>
如果没有 net/http 导入,运行此代码将导致“死锁”错误。这是因为 Extract 函数在没有相应调用 ServeHTTP 或 Close 的情况下被阻塞在 HTTP 请求上。
但是,如果导入了 net/http 包,即使没有调用 Extract 函数,也会出现“死锁”错误消失。这是因为导入 net 包会启动后台轮询自动与 HTTP 服务器通信的 Goroutines。
此行为记录在 Go 博客文章“NetHttp 中的 Goroutine Pooling”中:
“The net package 启动一个简单的后台 goroutine,定期测试 HTTP 服务器的可访问性。如果 HTTP 服务器不可访问,则简单的测试 goroutine 会退出,然后在服务器可访问时重新启动,这可确保调用中包含 net.Dial 的 goroutine。堆栈不会被错误地报告为被阻止。”
导入 net 包可以有效地禁用任何使用 net.Dial 的代码的死锁检测器,其中包括 HTTP 通信。
对于需要更严格的应用程序死锁检测,建议避免导入 net 包,直到需要与 HTTP 服务器建立通信。
以上是在 Go 中导入 net/http 包对死锁错误检测有何影响?的详细内容。更多信息请关注PHP中文网其他相关文章!