go等待N个线程完成操作总结

本文探讨了在Go语言中实现并发编程的两种方法:使用带缓存的通道(channel)进行任务同步与使用sync.WaitGroup等待所有协程完成。通过具体代码示例,展示了如何在多个后台线程中打印消息并确保所有线程正确结束。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一种,基于原生带缓存的channel

package main

import "fmt"

func main() {
	done := make(chan int, 10)
	for i := 0; i < cap(done); i++ {
		go func(j int) {
			fmt.Println("你好,世界" + fmt.Sprintf("%v", j))
			done <- 1
		}(i)
	}
	//等待N个后台线程完成
	for i := 0; i < cap(done); i++ {
		<-done
	}
}

  第二种,通过使用使用sync.WaitGroup来等待

package main

import (
	"sync"
	"fmt"
)

func main() {
	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(j int) {
			fmt.Println("你好,世界" + fmt.Sprintf("%v", j))
			wg.Done()
		}(i)
	}
	wg.Wait()
}

  

 

转载于:https://www.cnblogs.com/chenqionghe/p/9715968.html

<think>好的,我现在需要帮助用户在VSCode中使用Go语言编写多线程HTTP请求的代码。首先,我需要确认用户的需求,他们希望实现并发发送HTTP请求,可能用于性能测试或数据抓取等场景。用户提到了多线程,但Go语言中使用的是goroutine,所以需要明确术语上的区别,并指导正确的并发模型。 接下来,我需要考虑环境配置。用户使用VSCode,所以需要确保他们安装了Go插件,比如gopls和其他必要的工具,如gofumpt、goimports等。引用[3]提到设置GOPROXY为goproxy.cn,这对于国内用户下载依赖很重要,可能需要提醒用户检查代理配置,避免包下载问题。 然后是代码结构部分。Go的HTTP客户端通常使用net/http包,而并发处理则通过goroutine和sync.WaitGroup来实现。需要展示如何创建多个goroutine来发送请求,并等待所有请求完成。同时,错误处理和资源管理也很重要,比如使用defer关闭响应体,处理可能的panic。 还需要考虑示例代码的实用性。用户可能需要一个具体的例子,比如并发请求某个URL,并收集结果或统计时间。代码中需要包含必要的注释,解释关键步骤,比如创建WaitGroup、启动goroutine、处理响应等。 另外,引用[2]中提到的golang.org/x/sync包可能有用,比如errgroup.Group来管理错误,但可能对于简单示例来说,标准库的sync.WaitGroup已经足够。不过可以提到更高级的库供用户进一步探索。 测试和调试部分也很重要。用户可能在VSCode中遇到编译或运行时问题,需要指导如何安装依赖,运行代码,以及常见的错误处理,比如连接超时、处理429状态码等。引用[1]提到解决编译错误的能力很重要,所以示例代码必须语法正确,避免低级错误。 最后,生成相关问题,可能涉及性能优化、错误处理扩展、限流控制等,帮助用户深入理解。需要确保回答结构清晰,分步骤说明,代码格式正确,符合用户的要求。</think>以下是在VSCode中使用Go语言实现多线程HTTP请求的完整开发方法及示例代码: ### 一、环境准备 1. 安装Go语言插件:通过VSCode扩展商店安装`Go`官方插件(含gopls、代码补全等功能)[^3] 2. 配置代理(国内环境必需): ```bash go env -w GOPROXY=https://goproxy.cn,direct ``` ### 二、基础实现代码 ```go package main import ( "fmt" "net/http" "sync" "time" ) func main() { urls := []string{ "https://httpbin.org/get", "https://example.com", "https://jsonplaceholder.typicode.com/posts/1", } var wg sync.WaitGroup start := time.Now() for _, url := range urls { wg.Add(1) go func(targetUrl string) { defer wg.Done() resp, err := http.Get(targetUrl) if err != nil { fmt.Printf("请求失败 %s: %v\n", targetUrl, err) return } defer resp.Body.Close() fmt.Printf("%s 返回状态码: %d\n", targetUrl, resp.StatusCode) }(url) } wg.Wait() fmt.Printf("总耗时: %v\n", time.Since(start)) } ``` ### 三、关键实现点解析 1. **并发控制**:使用`sync.WaitGroup`确保主线程等待所有goroutine完成[^2] 2. **参数传递**:通过立即执行函数避免循环变量捕获问题 3. **资源管理**: - `defer resp.Body.Close()`确保响应体正确关闭 - 错误处理机制捕获网络请求异常 4. **性能度量**:通过`time.Since`计算总执行时间 ### 四、VSCode调试技巧 1. 按`F5`启动调试会话 2. 设置断点观察变量状态 3. 使用调试控制台查看goroutine状态 ### 五、优化建议 1. 连接池配置: ```go client := &http.Client{ Transport: &http.Transport{ MaxIdleConns: 100, IdleConnTimeout: 30 * time.Second, DisableCompression: true, }, Timeout: 10 * time.Second, } ``` 2. 使用`errgroup.Group`实现错误传播(需安装`golang.org/x/sync/errgroup`)[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值