go routine with time duration

huangapple go评论75阅读模式
英文:

go routine with time duration

问题

这段代码的目的是使用Go协程计算我的计算机与google.com之间的每个连接时间,但结果似乎是错误的。为什么时间一直在增加?这里发生了什么?

2013/12/04 16:10:41 www.google.com 597.175072ms
2013/12/04 16:10:41 www.google.com 608.161898ms
2013/12/04 16:10:41 www.google.com 614.527441ms
2013/12/04 16:10:41 www.google.com 620.51907ms
2013/12/04 16:10:41 www.google.com 630.052257ms
2013/12/04 16:10:42 www.google.com 654.539717ms
2013/12/04 16:10:42 www.google.com 659.144724ms
2013/12/04 16:10:42 www.google.com 1.282230659s
2013/12/04 16:10:42 www.google.com 1.353469764s

package main

import (
    "log"
    "net"
    "net/http"
    "time"
    "sync"
)

var wg sync.WaitGroup

func main() {
    url := "http://www.google.com"
    for i := 0; i < 9; i++ {
        wg.Add(1)
        go request(url)
    }
    wg.Wait()
}

func dialTimeout(network, addr string) (net.Conn, error) {
    return net.DialTimeout(network, addr, time.Duration(1*time.Second))
}

func request(url string) {
    var t0, t1 time.Time

    transport := http.Transport{
        Dial: dialTimeout,
    }

    client := http.Client{
        Transport: &transport,
    }
    t0 = time.Now()
    _, err := client.Get(url)
    t1 = time.Now()
    if err != nil {
        log.Println(err)
    }
    log.Println(url + " " + t1.Sub(t0).String())
    wg.Done()
}

这段代码的问题在于它使用了一个全局的等待组(sync.WaitGroup)来等待所有的Go协程完成。然而,在每个Go协程中,它们都会执行wg.Done()来通知等待组,但是在request函数中,wg.Done()的调用位置不正确,导致等待组在第一个Go协程完成后就被标记为已完成,从而导致后续的Go协程无法正确等待。

要解决这个问题,你可以将wg.Done()的调用位置移动到client.Get(url)之后,这样每个Go协程都能正确地通知等待组。

修正后的代码如下:

package main

import (
    "log"
    "net"
    "net/http"
    "time"
    "sync"
)

var wg sync.WaitGroup

func main() {
    url := "http://www.google.com"
    for i := 0; i < 9; i++ {
        wg.Add(1)
        go request(url)
    }
    wg.Wait()
}

func dialTimeout(network, addr string) (net.Conn, error) {
    return net.DialTimeout(network, addr, time.Duration(1*time.Second))
}

func request(url string) {
    var t0, t1 time.Time

    transport := http.Transport{
        Dial: dialTimeout,
    }

    client := http.Client{
        Transport: &transport,
    }
    t0 = time.Now()
    _, err := client.Get(url)
    t1 = time.Now()
    if err != nil {
        log.Println(err)
    }
    log.Println(url + " " + t1.Sub(t0).String())
    wg.Done()
}

修正后的代码会正确地等待所有的Go协程完成,并输出每个连接的时间。

英文:

The purpose of this code is to calculate each connected time between my computer and google.com using go routine.but the result seems wrong.why time keep increasing. what's go on here?

2013/12/04 16:10:41 www.google.com 597.175072ms

2013/12/04 16:10:41 www.google.com 608.161898ms

2013/12/04 16:10:41 www.google.com 614.527441ms

2013/12/04 16:10:41 www.google.com 620.51907ms

2013/12/04 16:10:41 www.google.com 630.052257ms

2013/12/04 16:10:42 www.google.com 654.539717ms

2013/12/04 16:10:42 www.google.com 659.144724ms

2013/12/04 16:10:42 www.google.com 1.282230659s

2013/12/04 16:10:42 www.google.com 1.353469764s

package main
import (
&quot;log&quot;
&quot;net&quot;
&quot;net/http&quot;
&quot;time&quot;
&quot;sync&quot;
)
var wg sync.WaitGroup
func main() {
url := &quot;http://www.google.com&quot;
for i := 0; i &lt; 9; i++ {
wg.Add(1)
go request(url)
}
wg.Wait()
}
func dialTimeout(network, addr string) (net.Conn, error) {
return net.DialTimeout(network, addr, time.Duration(1*time.Second))
}
func request(url string) {
var t0, t1 time.Time
transport := http.Transport{
Dial: dialTimeout,
}
client := http.Client{
Transport: &amp;transport,
}
t0 = time.Now()
_, err := client.Get(url)
t1 = time.Now()
if err != nil {
log.Println(err)
}
log.Println(url +&quot; &quot;+ t1.Sub(t0).String())
wg.Done()
}

答案1

得分: 3

也许这是解释的方式:你的代码是一种聪明的方法,将10个连接时间从最快到最慢进行排序。每个goroutine在完成后打印所需的时间,因此较长的连接稍后打印。由于它们基本上同时开始,你会看到“连接时间增加”,但实际上没有增加,只是最慢的连接较慢,并在最后打印。

http://play.golang.org/p/MzgELyNh8B 展示了这种效果。

英文:

Maybe this is the explanation: Your code is a clever way to sort the 10 connection times from fastest to slowest. Each goroutine prints the needed time once it is finished, so longer connections are printed later. As all start basically at the same moment you see "increasing connection times" but nothing is increasing, the slowest are just slow and print at the end.

http://play.golang.org/p/MzgELyNh8B shows the effect.

huangapple
  • 本文由 发表于 2013年12月4日 16:37:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/20370576.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定