Beego - gorountine改造项目功能

gorountine demo

package controllers

import (
	"fmt"
	"github.com/astaxie/beego"
	"time"
)

type GoDemoController struct {
	beego.Controller
}

// go协程打印顺序不一致(并行)
// @router /go/demo [*]
func (this *GoDemoController) Demo() {
	for i := 0; i < 10; i++ { // 启动10个任务
		go cal(i)
	}
	time.Sleep(2 * time.Second)
	this.Ctx.WriteString("demos")
}
func cal(i int) {
	fmt.Printf("i= %d\n", i)
}

/**
channel demo
*/
// 打印顺序不一致(并行)
// @router /go/channel/demo [*]
func (this *GoDemoController) ChannelDemo() {
	Channel := make(chan bool, 10) // 带缓冲
	for i := 0; i < 10; i++ {
		// 为什么go访问? 如果是无缓冲的channel,在一个goroutine中实现发送和接收会发生死锁
		go cal1(i, Channel)
	}

	for j := 0; j < 10; j++ {
		<-Channel
	}
	close(Channel)
	time.Sleep(2 * time.Second)
	this.Ctx.WriteString("demos")
}

func cal1(i int, Channel chan bool) {
	fmt.Printf("i= %d\n", i)
	time.Sleep(2 * time.Second)
	Channel <- true
}

/*
select demo
*/
// 写for打印no message
// @router /go/select/demo [*]
func (this *GoDemoController) SelectDemo() {
	ChannelOne := make(chan int, 20)
	ChannelTwo := make(chan string, 20)
	go cal2(ChannelOne)

	ChannelTwo <- "a"
	ChannelTwo <- "b"
	go func() {
		//for {
		select {
		case a := <-ChannelOne:
			fmt.Println("get one = ", a)
		case b := <-ChannelTwo:
			fmt.Println("get two = ", b)
		default:
			fmt.Println("no message")

		}
		//}
	}()
	this.Ctx.WriteString("select demo")
}
func cal2(oneChannel chan int) {
	for i := 0; i < 10; i++ {
		oneChannel <- i
		fmt.Println("set one = ", i)
	}
}

/**
模拟任务池
*/

// @router /go/task/demo [*]
func (this *GoDemoController) TaskDemo() {
	// 接收任务
	taskChannel := make(chan int, 20)
	// 处理任务
	resChannel := make(chan int, 20)
	// 关闭任务
	closeChannel := make(chan bool, 5)

	go func() {
		for i := 0; i < 10; i++ {// 启动10个任务
			taskChannel <- i
		}
		close(taskChannel)
	}()
	// 处理任务
	for i := 0; i < 5; i++ {
		go Task(taskChannel, resChannel, closeChannel)
		fmt.Println("处理任务", i)
	}

	// 当接收5个值后,说明5个任务都执行完成
	go func() {
		for i := 0; i < 5; i++ {
			<-closeChannel // 从closeChannel获取值 , 没有值就会阻塞在这里
		}
		close(resChannel)
		close(closeChannel)
	}()

	// for循环reschannel时,当channel关闭以后会退出循环
	for i := range resChannel {
		fmt.Println("res : ", i)
	}

	this.Ctx.WriteString("模拟任务池")
}

func Task(taskChannel chan int, resChannel chan int, closeChannel chan bool) {
	for t := range taskChannel {
		// 从task中拿出值 写入res中
		resChannel <- t
	}
	// 写入状态到close
	closeChannel <- true

}

原代码

// 获取评论列表
// @router /comment/ormlist [*]
func (this *CommentController) ORMList() {
	// 获取剧集数
	episodesId, _ := this.GetInt("episodesId")
	// 获取页码
	limit, _ := this.GetInt("limit")
	offset, _ := this.GetInt("offset")

	if episodesId == 0 {
		this.Data["json"] = ReturnError(4001, "请选定剧集")
		this.ServeJSON()
	}

	if limit == 0 {
		limit = 12
	}

	num, comments, err := models.GetCommentList(episodesId, offset, limit)
	if err != nil {
		this.Data["json"] = ReturnError(4004, "没有相关内容")
		this.ServeJSON()
	}
	var data []CommentInfo
	var commentInfo CommentInfo
	for _, v := range comments {
		commentInfo.Id = v.Id
		commentInfo.Content = v.Content
		commentInfo.AddTime = v.AddTime
		commentInfo.AddTimeTitle = DateFormat(v.AddTime)
		commentInfo.UserId = v.UserId
		commentInfo.Stamp = v.Stamp
		commentInfo.PraiseCount = v.PraiseCount
		fmt.Println(v.UserId)
		// 获取用户信息
		commentInfo.UserInfo, _ = models.RedisGetUserInfo(v.UserId)

		data = append(data, commentInfo)
	}
	this.Data["json"] = ReturnSuccess(0, "success", data, num)
	this.ServeJSON()
}

goroutine修改后

// 获取评论列表
// goroutine改造获取用户信息: 达到同时获取
// @router /comment/list [*]
func (this *CommentController) List() {
	// 获取剧集数
	episodesId, _ := this.GetInt("episodesId")
	// 获取页码
	limit, _ := this.GetInt("limit")
	offset, _ := this.GetInt("offset")

	if episodesId == 0 {
		this.Data["json"] = ReturnError(4001, "请选定剧集")
		this.ServeJSON()
	}

	if limit == 0 {
		limit = 12
	}

	num, comments, err := models.GetCommentList(episodesId, offset, limit)
	if err != nil {
		this.Data["json"] = ReturnError(4004, "没有相关内容")
		this.ServeJSON()
	}
	var data []CommentInfo
	var commentInfo CommentInfo

	// goroutine 改造
	//获取uid Channel
	uidChannel := make(chan int, 12) // 总共查询12条 
	closeChannel := make(chan bool, 5)
	//结果channel
	resChannel := make(chan models.UserInfo, 12)// 总共查询12条 

	// 把获取的uid放进channel中
	go func() {
		for _, v := range comments {
			uidChannel <- v.UserId
		}
		close(uidChannel)
	}()
	// 处理uidChannel中的信息
	for i := 0; i < 5; i++ {    // 启动5个任务
		go chanGetUserInfo(uidChannel, resChannel, closeChannel)
	}
	// 判断是否执行完成
	go func() {
		for i := 0; i < 5; i++ {
			<-closeChannel
		}
		close(resChannel)
		close(closeChannel)
	}()

	// reschannel 中获取数据
	userInfoMap := make(map[int]models.UserInfo)
	for r := range resChannel {
		userInfoMap[r.Id] = r
	}
	for _, v := range comments {
		commentInfo.Id = v.Id
		commentInfo.Content = v.Content
		commentInfo.AddTime = v.AddTime
		commentInfo.AddTimeTitle = DateFormat(v.AddTime)
		commentInfo.UserId = v.UserId
		commentInfo.Stamp = v.Stamp
		commentInfo.PraiseCount = v.PraiseCount
		fmt.Println(v.UserId)
		// 获取用户信息
		commentInfo.UserInfo, _ = userInfoMap[v.UserId]

		data = append(data, commentInfo)
	}

	this.Data["json"] = ReturnSuccess(0, "success", data, num)
	this.ServeJSON()
}

func chanGetUserInfo(uidchannel chan int, resChannel chan models.UserInfo, closeChannel chan bool) {
	for uid := range uidchannel {
		res, err := models.RedisGetUserInfo(uid)
		fmt.Println(res)
		if err == nil {
			resChannel <- res
		}
	}
	closeChannel <- true
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苗先生的PHP记录

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值