Golang中如何运行指定时长的goroutine
Golang中如何运行指定时长的goroutine
我是 Go 语言的新手。我正在通过编写一个简单的工具来学习 Go,该工具通过并发发送请求来测试 URL 的性能。
我已经使用 waitgroup 和 go routines 实现了并发。但是,我无法让我的程序执行 t 时长。
NewTicker 每隔 t 秒发送一次请求。但我希望 goroutine 能运行 t 时长。
请问有什么见解吗?谢谢!
2 回复
我认为你需要的是 context.WithTimeout(t)。然后使用该上下文或由其派生的上下文来使请求过期。
func main() {
fmt.Println("hello world")
}
更多关于Golang中如何运行指定时长的goroutine的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中运行指定时长的goroutine,可以使用context.WithTimeout或time.After。以下是两种实现方式:
1. 使用context.WithTimeout(推荐)
package main
import (
"context"
"fmt"
"time"
)
func worker(ctx context.Context, id int) {
for {
select {
case <-ctx.Done():
fmt.Printf("Worker %d stopped\n", id)
return
default:
// 执行你的请求逻辑
fmt.Printf("Worker %d sending request...\n", id)
time.Sleep(500 * time.Millisecond) // 模拟请求
}
}
}
func main() {
duration := 5 * time.Second // 指定运行时长
ctx, cancel := context.WithTimeout(context.Background(), duration)
defer cancel()
// 启动多个goroutine
for i := 1; i <= 3; i++ {
go worker(ctx, i)
}
// 等待指定时长
<-ctx.Done()
time.Sleep(100 * time.Millisecond) // 等待所有goroutine退出
fmt.Println("All workers stopped")
}
2. 使用time.After
package main
import (
"fmt"
"sync"
"time"
)
func worker(stopChan <-chan struct{}, id int, wg *sync.WaitGroup) {
defer wg.Done()
for {
select {
case <-stopChan:
fmt.Printf("Worker %d stopped\n", id)
return
default:
// 执行你的请求逻辑
fmt.Printf("Worker %d sending request...\n", id)
time.Sleep(500 * time.Millisecond) // 模拟请求
}
}
}
func main() {
duration := 5 * time.Second // 指定运行时长
stopChan := make(chan struct{})
var wg sync.WaitGroup
// 启动多个goroutine
for i := 1; i <= 3; i++ {
wg.Add(1)
go worker(stopChan, i, &wg)
}
// 设置超时
time.AfterFunc(duration, func() {
close(stopChan)
})
wg.Wait()
fmt.Println("All workers stopped")
}
3. 针对你的URL测试工具的具体实现
func testURLs(duration time.Duration, urls []string) {
ctx, cancel := context.WithTimeout(context.Background(), duration)
defer cancel()
var wg sync.WaitGroup
results := make(chan string, len(urls))
for _, url := range urls {
wg.Add(1)
go func(u string) {
defer wg.Done()
for {
select {
case <-ctx.Done():
return
default:
// 发送HTTP请求
start := time.Now()
resp, err := http.Get(u)
latency := time.Since(start)
if err != nil {
results <- fmt.Sprintf("%s: error - %v", u, err)
} else {
results <- fmt.Sprintf("%s: %s - latency: %v",
u, resp.Status, latency)
resp.Body.Close()
}
time.Sleep(100 * time.Millisecond) // 请求间隔
}
}
}(url)
}
// 收集结果
go func() {
wg.Wait()
close(results)
}()
for result := range results {
fmt.Println(result)
}
}
第一种方法使用context更符合Go的并发模式,能更好地控制goroutine的生命周期。第二种方法使用channel也能达到相同效果。两种方法都能确保goroutine在指定时长后停止执行。

