gpt4 book ai didi

go - 为什么带有网络 I/O 的 goroutines 被阻塞了?

转载 作者:IT王子 更新时间:2023-10-29 00:48:36 25 4
gpt4 key购买 nike

我在 Ubuntu 13.04 上使用 go 1.1 devel

go version devel +ebe8bca920ad Wed May 15 15:34:47 2013 +1000 linux/386

根据 http://golang.org/doc/faq#goroutines

When a coroutine blocks, such as by calling a blocking system call, the run-time automatically moves other coroutines on the same operating system thread to a different, runnable thread so they won't be blocked.

我正在尝试编写一个下载器,它可以使用 goroutines 分 block 下载一个大文件这是我想出的最好的 goroutine:

func download(uri string, chunks chan int, offset int, file *os.file) {
for current := range chunks {

fmt.println("downloading range: ", current, "-", current+offset)

client := &http.client{}
req, _ := http.newrequest("get", uri, nil)
req.header.set("range: ", fmt.sprintf("bytes=%d-%d", current, current+offset))
resp, err := client.do(req)
if err != nil {
panic(err)
}
defer resp.body.close()
body, err := ioutil.readall(resp.body)
if err != nil {
panic(err)
}
file.write(body)
}
}

完整脚本可在 https://github.com/tuxcanfly/godown/blob/master/godown.go 获得

尽管文件正在正确下载和保存,但我可以看到第二个 block 开始了只有当第一个完成时。

分 block 下载不应该并行运行,还是我做错了什么?

最佳答案

您只有一个 goroutine 下载 block 。

第 64 行:

go download(*download_url, chunks, offset, file)

你可能想要的是:

for i := 0; i < *threads; i++ {
go download(*download_url, chunks, offset, file)
}

这将立即下载 *threads 个 block 。


并发工作后,您可能会注意到第 29 行没有按您的预期工作。如果 block 1 在 block 2 之前完成,则这些部分将被乱序写入。您可能想改用 http://golang.org/pkg/os/#File.WriteAt .


您的 Range header 也有两个问题。

  1. 您不下载其余部分。如果文件大小为 3002 并且您有 3 个线程,它将请求 0-1000、1000-2000、2000-3000,并且永远不会下载最后 2 个字节。
  2. 字节范围包括在内。这意味着你(正如你在前面的例子中看到的那样)下载了一些字节两次。字节 1000 和 2000 被请求了两次。当然,只要你写到正确的位置,你应该不会有太大的问题。

通过将第 19 行从

req.Header.Set("Range: ", fmt.Sprintf("bytes=%d-%d", current, current+offset))

对此

req.Header.Set("Range: ", fmt.Sprintf("bytes=%d-%d", current, current+offset-1))

有关 Range header 的更多信息,我建议阅读 Section 14.35 in RFC2616

关于go - 为什么带有网络 I/O 的 goroutines 被阻塞了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16642799/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com