欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 游戏 > 玩转goroutine:Golang中对goroutine的应用

玩转goroutine:Golang中对goroutine的应用

2025/2/8 4:29:02 来源:https://blog.csdn.net/u011313034/article/details/145432481  浏览:    关键词:玩转goroutine:Golang中对goroutine的应用

文章目录

    • 前言
    • 需求说明
    • 目录结构说明
    • 需求拆分
      • 步骤一:配置HTTP服务
      • 步骤二:创建并发任务的实现
        • 代码解释
      • 步骤三:启动服务并测试
    • 总结以及进阶优化

前言

上一篇文章讲到了goroutine的基本原理和概念的理解,本次将基于 玩转goroutine:Golang中对goroutine的理解述 这篇文章的内容来写一个API接口,实现goroutine并发处理任务。

需求说明

本次将创建一个简单的示例,展示如处理并发请求。我们将从具体的目录结构出发,实现一个/process的API接口,触发的时候会启动多个goroutine来并发处理任务,并且使用sync.WaitGroup来等待所有并发任务完成。

目录结构说明

  • cmd/web-app/main.go:程序主入口,启动HTTP服务
  • internal/home/model.go:存放需求相关的业务逻辑
  • internal/user/handle.go:处理用户请求相关的代码
  • pkg/auth/jwt.go:用于认证的JWT代码(本次暂时用不到,保留作为示例)
  • pkg/config/config.go:全局配置文件

需求拆分

  • /process接口中,接收到请求后,启动多个goroutine来并发处理任务。
  • 每个goroutine模拟一个简单的任务(比如打印任务ID,模拟耗时操作等等)
  • 在所有任务完成后,返回一个成功响应到接口。

步骤一:配置HTTP服务

cmd/web-app/main.go中,设置HTTP服务,注册/process接口,并启动服务

// @title           My E-Commerce API
// @version         1.0
// @description     This is the API documentation for My E-Commerce platform.
// @termsOfService  http://example.com/terms/// @contact.name    API Support
// @contact.url     http://example.com/support
// @contact.email   support@example.com// @license.name    MIT
// @license.url     https://opensource.org/licenses/MIT// @host            localhost:8088
// @BasePath
package mainimport ("database/sql""log""my-ecommerce-app/internal/task" // 引入任务处理模块"my-ecommerce-app/pkg/config"_ "my-ecommerce-app/docs""github.com/gin-gonic/gin"_ "github.com/go-sql-driver/mysql" // 导入 MySQL 驱动swaggerFiles "github.com/swaggo/files"ginSwagger "github.com/swaggo/gin-swagger"
)func main() {config.LoadConfig() // 加载配置// 使用配置连接数据库dsn := config.Appconfig.DBUser + ":" + config.Appconfig.DBPassword + "@tcp(" + config.Appconfig.DBHost + ")/" + config.Appconfig.DBNamedb, err := sql.Open("mysql", dsn)if err != nil {log.Fatalf("无法连接到数据库:%v", err)}defer db.Close()// 数据库连接if err = db.Ping(); err != nil {log.Fatalf("数据库连接失败:%v", err)}// 初始化 Gin 引擎r := gin.New()// 注册路由r.GET("/api/process", task.ProcessHandler)// 添加swagger 路由r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))// 启动服务if err := r.Run(":8088"); err != nil {log.Fatalf("无法启动服务器:%v", err)}
}

步骤二:创建并发任务的实现

internal/user/handle.go中,实现并发处理任务的逻辑

package taskimport ("fmt""github.com/gin-gonic/gin""sync""time"
)// ProcessTask 模拟一个处理任务的函数
func ProcessTask(taskID int, wg *sync.WaitGroup) {// 在goroutine结束时通知WaitGroupdefer wg.Done()// 模拟任务耗时fmt.Printf("Task %d started\n", taskID)time.Sleep(2 * time.Second) // 模拟耗时操作fmt.Printf("Task %d completed\n", taskID)
}// ProcessHandler 处理并发任务请求的HTTP处理器
func ProcessHandler(c *gin.Context) {// 创建WaitGroup来同步goroutinevar wg sync.WaitGroup// 假设我们要启动5个goroutine来并发处理任务taskCount := 5for i := 1; i <= taskCount; i++ {wg.Add(1) // 每启动一个goroutine,WaitGroup计数加1go ProcessTask(i, &wg) // 启动一个新的goroutine来处理任务}// 等待所有goroutine完成wg.Wait()// 返回响应c.JSON(200, gin.H{"message": "All tasks completed successfully!",})
}
代码解释
  1. ProcessTask函数:
    • 创建的一个模拟任务处理函数。它会接收一个taskIDsync.WaitGroup作为参数
    • 在函数结束时,我们调用wg.Done()来通知WaitGroup当前的goroutine已经完成。
  2. ProcessHandler函数:
    • 这是处理/process接口的HTTP处理器
    • 定义来一个sync.WaitGroup来确保所有的goroutine都完成后才返回响应到接口
    • 通过wg.Add(1)来告知WaitGroup有一个新的goroutine启动,每当一个任务完成时,调用wg.Done()
    • 最后,调用wg.Wait()来阻塞主线程,直到所有的goroutine都执行完毕。

步骤三:启动服务并测试

  • 启动Go服务:go run cmd/web-app/main.go
  • 访问http://127.0.0.1:8088/api/process来测试接口。在控制台可以看到并发任务的处理过程,任务完成后接口将返回All tasks completed successfully!

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结以及进阶优化

  • 任务处理过程中,我们模拟了time.Sleep来表示任务的耗时。在实际项目中,可以替换成实际的业务逻辑,比如数据库操作调用微服务等。
  • 如果任务数量较多,或者每个任务执行时间较长,考虑引入任务池(Worker Pool)来限制并发数,避免过多的goroutine造成系统资源的浪费
    对于错误处理和超时处理,可以在goroutine中添加适当的error返回和context控制

以上就是一个基于goroutine的并发处理API。有任何问题,欢迎在评论区与我互动,感谢各位的观看~

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com