package mainimport ("context""fmt""math/rand""sync""time"
)// 模拟的数据结构
type UserInfo struct {ID intName stringAge int
}type OrderHistory struct {Orders []stringTotal float64
}type Recommendations struct {Items []string
}// 模拟的数据库/API客户端
type APIClient struct{}// 1. 获取用户信息(模拟数据库查询)
func (c *APIClient) GetUserInfo(ctx context.Context, userID int) (*UserInfo, error) {select {case <-ctx.Done():fmt.Println("GetUserInfo: 请求被取消")return nil, ctx.Err()case <-time.After(time.Duration(rand.Intn(2000)) * time.Millisecond): // 模拟0-2秒延迟return &UserInfo{ID: userID, Name: fmt.Sprintf("用户%d", userID), Age: 25}, nil}
}// 2. 获取订单历史(模拟外部API调用)
func (c *APIClient) GetOrderHistory(ctx context.Context, userID int) (*OrderHistory, error) {// 模拟10%的失败率if rand.Intn(10) == 0 {return nil, fmt.Errorf("订单服务暂时不可用")}select {case <-ctx.Done():fmt.Println("GetOrderHistory: 请求被取消")return nil, ctx.Err()case <-time.After(time.Duration(800+rand.Intn(1200)) * time.Millisecond): // 0.8-2秒延迟return &OrderHistory{Orders: []string{"订单A", "订单B", "订单C"},Total: 299.99,}, nil}
}// 3. 获取推荐内容(模拟缓存查询)
func (c *APIClient) GetRecommendations(ctx context.Context, userID int) (*Recommendations, error) {select {case <-ctx.Done():fmt.Println("GetRecommendations: 请求被取消")return nil, ctx.Err()case <-time.After(time.Duration(rand.Intn(1000)) * time.Millisecond): // 0-1秒延迟return &Recommendations{Items: []string{"推荐商品A", "推荐商品B", "推荐商品C"},}, nil}
}// 聚合器:并发获取所有数据
type Aggregator struct {client *APIClient
}// Result 包装每个请求的结果
type Result struct {DataType string // 数据类型Data interface{} // 实际数据Err error // 错误信息
}// AggregateUserData 并发聚合用户数据
func (a *Aggregator) AggregateUserData(ctx context.Context, userID int) map[string]interface{} {// 创建带有超时的上下文(3秒后超时)ctx, cancel := context.WithTimeout(ctx, 3*time.Second)defer cancel() // 确保释放资源// 创建带缓冲的channel,避免goroutine泄漏resultChan := make(chan Result, 3)var wg sync.WaitGroup// 1. 启动获取用户信息的goroutinewg.Add(1)go func() {defer wg.Done()userInfo, err := a.client.GetUserInfo(ctx, userID)resultChan <- Result{"user_info", userInfo, err}}()// 2. 启动获取订单历史的goroutinewg.Add(1)go func() {defer wg.Done()orders, err := a.client.GetOrderHistory(ctx, userID)resultChan <- Result{"order_history", orders, err}}()// 3. 启动获取推荐内容的goroutinewg.Add(1)go func() {defer wg.Done()recommendations, err := a.client.GetRecommendations(ctx, userID)resultChan <- Result{"recommendations", recommendations, err}}()// 独立的goroutine等待所有任务完成并关闭channelgo func() {wg.Wait()close(resultChan)}()// 主goroutine收集结果results := make(map[string]interface{})// 关键部分:使用select监听多个channelfor {select {case <-ctx.Done():// 上下文被取消或超时fmt.Printf("\n聚合请求超时或被取消: %v\n", ctx.Err())// 尝试收集已经完成的结果fmt.Println("已收集到的部分结果:")for k, v := range results {fmt.Printf(" %s: %v\n", k, v)}// 添加超时标记results["timeout"] = truereturn resultscase result, ok := <-resultChan:if !ok {// channel已关闭,所有结果收集完成fmt.Println("\n所有请求完成!")return results}// 处理单个结果if result.Err != nil {fmt.Printf("获取 %s 失败: %v\n", result.DataType, result.Err)results[result.DataType+"_error"] = result.Err.Error()} else {fmt.Printf("成功获取 %s\n", result.DataType)results[result.DataType] = result.Data}}}
}func main() {fmt.Println("=== Go并发编程示例:API数据聚合 ===")client := &APIClient{}aggregator := &Aggregator{client: client}// 测试1: 正常情况fmt.Println("测试1: 正常请求(3秒超时)")fmt.Println("------------------------")start := time.Now()results := aggregator.AggregateUserData(context.Background(), 123)elapsed := time.Since(start)fmt.Printf("\n总耗时: %v\n", elapsed)fmt.Printf("收集到的数据类型数量: %d\n\n", len(results))// 显示部分结果if userInfo, ok := results["user_info"]; ok {fmt.Printf("用户信息: %+v\n", userInfo)}// 测试2: 模拟手动取消fmt.Println("\n\n测试2: 手动取消请求")fmt.Println("-------------------")ctx, cancel := context.WithCancel(context.Background())// 启动一个goroutine在500ms后取消请求go func() {time.Sleep(500 * time.Millisecond)fmt.Println("\n发送取消信号...")cancel()}()start = time.Now()results = aggregator.AggregateUserData(ctx, 456)fmt.Println("results", results)elapsed = time.Since(start)fmt.Printf("\n请求在 %v 后被取消\n", elapsed)// 测试3: 模拟外部中断fmt.Println("\n\n测试3: 模拟外部中断处理")fmt.Println("-----------------------")interruptChan := make(chan struct{}, 1)// 创建一个可以响应中断的上下文ctx, cancel = context.WithCancel(context.Background())defer cancel()// 模拟外部中断(如用户按Ctrl+C)go func() {time.Sleep(700 * time.Millisecond)fmt.Println("\n[系统] 收到中断信号")interruptChan <- struct{}{}}()// 启动聚合请求go func() {results := aggregator.AggregateUserData(ctx, 789)fmt.Printf("\n中断测试结果: %d个数据项\n", len(results))}()// 监听中断信号select {case <-interruptChan:fmt.Println("[系统] 正在取消所有请求...")cancel() // 取消上下文time.Sleep(100 * time.Millisecond) // 给goroutine一些时间响应case <-time.After(2 * time.Second):fmt.Println("[系统] 未收到中断信号")}time.Sleep(1 * time.Second) // 等待所有输出完成fmt.Println("\n=== 示例结束 ===")
}本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/989169.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!相关文章
2025/12/5 今天学gemini的day1 lecode1和26等
2025/12/5 今天学gemini的day1 lecode1和26等两数之和 (LeetCode 1)
考察点: 哈希表 (std::unordered_map) 的使用。
遍历数组,每遇到一个数 num,去哈希表里找有没有 target - num。如果有,返回下标;如果没有,把…
2025年必看:花灯厂家排行,彩车花灯工艺谁更优?华景花灯/夜景布置灯/商场美陈花灯/古镇花灯/演绎花灯生产商有哪些
随着文旅产业的深度融合与夜间经济的蓬勃发展,彩车花灯作为集文化展示、节庆氛围与流动景观于一体的重要载体,其市场需求持续升温。优秀的彩车花灯不仅考验厂家的传统工艺功底,更对其创意设计、技术集成、项目落地及…
银河麒麟V10 申威架构 docker-compose rpm 包安装教程(附命令)
银河麒麟V10 申威架构 docker-compose rpm 包安装教程(附命令)1. 先确认系统环境你是 申威架构(SW64),别搞错成 x86 或 ARM。系统是 银河麒麟(Kylin)V10,包名里有 ky10就是对应这个版本。先看看有没有 root …
102302104刘璇-数据采集与融合技术实践作业4
作业1:
要求:熟练掌握 Selenium 查找 HTML 元素、爬取 Ajax 网页数据、等待 HTML 元素等内容。使用 Selenium 框架+ MySQL 数据库存储技术路线爬取“沪深 A 股”、“上证 A 股”、“深证 A 股”3 个板块的股票数据信息…
【Linux】服务器开启 ssh 服务 ssh 相关配置
✨ 操作系统
Ubuntu 24.04.3 LTS✨ 开启 ssh 服务
安装 ssh 服务
sudo apt update
sudo apt install openssh-server -y检查 ssh 服务状态
sudo systemctl status ssh如果回显绿色则表示 ssh 服务已开启✨ 修改 ssh 端…
Meta 挖角苹果设计师,重塑 AI 硬件交互;健康追踪应用 Healthify 升级 AI 助手:实时语音与摄像头交互丨日报
开发者朋友们大家好:这里是 「RTE 开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的技术」、「有亮点的产品」、「有思考的文章」、「有态度…
国产操作系统凝思磐石4.x x86架构镜像下载
凝思磐石 国产linux操作系统
rocky4.2.40-x86_64-security-2014-07-04.iso
https://pan.baidu.com/s/1nVBZEx4r7pt42MX79R-IbQ
提取码: z616
国产系统但是镜像叫做rocky linux,你说奇怪不奇怪?文件名称:rocky4.2.40…
2025 省选 炼石计划 梦熊模拟赛 记录
2025 炼石计划 梦熊模拟赛 记录
#1
总结
T1难难难难难。
T2T3唐爆了,(几乎)过了。
分数:0+90+(90)=180。
T1
怎么这么难,harddddd。
考虑找到连通块的直径的中心,然后奇偶分讨一下。
考虑奇数时,有唯一中心,…
LocalAI:一个免费开源的AI替代实用的方案,让创意更自由!
pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …
全面解析DoS攻击:防御策略与应急响应指南
本文深入探讨拒绝服务攻击的工作原理、三种主要攻击类型及对企业的影响,详细介绍了包括风险评估、攻击面缩减、第三方防护服务在内的多层次防护策略,并提供了包含升级流程和业务连续性措施的应急响应计划。如何防范D…
要提高脑电模型的准确性,就必须让模型学会“无视个体差异”,抓住真正稳定、跨人的特征。
🧠 一、为什么脑电难?
脑电 EEG 有三大“不稳定”:
1)不同时间:电极位置轻微挪动、皮肤状况不同
2)不同人:头型、脑沟、皮肤阻抗都不同
3)同一个人:疲劳、情绪、生理状态不同
所以“原始 EEG”是非常漂的,不…
AI如何赋能游戏,为所有玩家创造更佳体验
本文探讨人工智能如何通过辅助工具和动态难度调整等技术,提升游戏的可访问性与个性化体验,使其更适应不同能力玩家的需求。当某中心揭晓"Project Gameface"时,该公司自豪地展示了一款无需手部操作、由AI驱…
cnn/rnn/Transformer
特征
CNN
RNN
Transformer看数据方式
看一小块
按顺序看
一次全看优势
提空间特征
处理时序
全局相关性强、效果最好速度
快
慢(逐步计算)
很快(并行)适合EEG
图空间、频率
短序列、时序
长序列、多导联、跨人任务…
PbootCMS网站转移后无法打开报错提示“No input file specifed”
在将 PbootCMS 网站迁移到新环境后,如果出现“No input file specified”错误,通常是由于服务器配置或文件问题导致的。以下是解决该问题的具体方法:1. 检查根目录中的 .user.ini 文件原因:.user.ini 文件可能包含…
kanass零基础学习,项目负责人如何启用kanass驾驭项目
pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …
意义的行为化:AI时代法律体系的数字通译与演进之道
意义的行为化:AI时代法律体系的数字通译与演进之道
摘要
人工智能技术的深度应用正在引发法律治理范式的历史性重构。本文提出“意义行为原生”这一核心范式,主张数字时代的法律效力,必须源自其价值能被系统性地编译…