能不能终止函数的运行

情况是这样

我需要 http Get 去获取一个东西

但是 我为了效率 开启了10个goroutine
恰巧这个网站服务器太不稳定了 有时候 会超时20秒什么的

我现在想 这10个程序中如果有一个返回了 就立马终止掉另外的9个

绞尽脑汁 怎么都觉得这个东西 怎么都搞不定

我设定http clent 的超时是 30秒

程序是会等到30秒才会结束的 不知道怎么 强行终止掉函数的运行

就像在程序正在运行的过程中 强行kill进程一样

共 10 个回复


qq19116699

自己解决了

package main

import (
    "fmt"
    "net/http"
    "time"
)

func main() {

    req, _ := http.NewRequest("GET", "http://www.google.com/", nil)
    transport := &http.Transport{}

    go func() {
        time.Sleep(3e9)
        transport.CancelRequest(req)
        fmt.Println(&req)
    }()
    t := time.Now()
    transport.RoundTrip(req)
    fmt.Println(time.Since(t))

}
# 0

stevewang

你用一个长度为10的channel来做就可以,10个goroutine去访问网络获取数据写入channel,再创建一个额外的goroutine从这个channel一次性读取数据。

某个goroutine首先返回数据以后,其余的访问网络的goroutine就不用管它们了,不需要去强制结束它们,它们执行完成以后会自行销毁自身goroutine(只要网络连接释放掉就可以)。

# 1

qq19116699

@stevewang
我还是觉得如果是这样的非常浪费资源
就好比 你派出10名队员出去寻找一个人
他们分别去往不同的路线
约好 无论如何30后天回来交任务

结果他们其中一个出去第一天就找到了要找的人
就应该通知其余9个不要找了

假如说他们每个人每天出去的消费是100元 那不就节省了 9 X 100 X 29 元

# 2

stevewang

是否浪费资源要看这个任务的重要性而言。如果这个任务不是非常重要的话,其实一个goroutine去做HttpGet就可以。
我说的这个模式在google搜索引擎里有用到,目的是最快返回查询结果。

# 3

hansonzh

@qq19116699
贴出来的程序的意思是不是3e9 ns后,RoundTrip 没有返回response,连接就会被CancelRequest关闭。但是貌似上面的程序执行的话一直卡在那,这是为什么?
刚接触golang不久,小白一个,请指教!

# 4

qq19116699

@hansonzh
这个就是为了模拟取消请求 等3秒后 发送了取消请求的命令
这个时候 程序会中断

应该不会卡住 我测试了 没问题的

# 5

hansonzh

确实没有卡住,原来发现在我的机器上要1分钟15秒左右才能返回,我试了好几次,每次差不多都在这个数。三秒后就取消请求了,为什么要等这么长时间?

# 6

hansonzh

我刚又在windows上试了一下,确实在3s边上就返回,但是在Mac的机器上却要1分多钟。竟然与环境有关,真是奇怪,望高人指教

# 8

David

@hansonzh 你不要等待 request 返回,起一个 goroutine 去取消就好了,其他的 routine 等 cancel 或者完成自己会结束的。

# 9