Golang面试题: 并发编程相关

开心一刻

       虽然经常被老婆打,但苍天可鉴,老婆并非是不讲理的人。每次打之前,都会征求我的同意,我说不同意,她就打到我同意。

题目介绍

       有三个需要并发执行的函数,三个函数会返回同一类型的值,且三个函数执行时间在2ms到10ms之间不等,而主程序要求在5ms内返回结果,若5ms内没有执行完毕,则强制返回结果,这个时候某个函数可能还没有返回因此没有值。下面是我的做法,纯属个人写法。

并发编程

这里的三个函数分别是:
func searchText(query string) Result
func searchImage(query string) Result
func searchVideo(query string) Result
三个函数除了函数名称不同,参数和返回值均相同,函数内部就是具体的调用逻辑了,因为这里不关心,所以统一使用time.Sleep方法来模拟函数的执行时间。

package main

import (
	"context"
	"fmt"
	"time"
)

type Result string
func searchText(query  string) Result {
	time.Sleep(5*time.Millisecond)
	return "text"
}
func searchImage(query  string) Result {
	time.Sleep(2*time.Millisecond)
	return "image"
}
func searchVideo(query  string) Result {
	time.Sleep(4*time.Millisecond)
	return "video"
}
//  Search是其中的主体代码,ctx是Context类型的对象,用来超时退出
func Search(ctx context.Context, query string) []Result {
	var (
		result []Result
		// ch被用来接收返回值,ch属于同步channel,如果二个函数都返回,那么在第一个返回值被读取之前,第二个将会被阻塞。
		ch = make(chan Result)
	)
	// 因为这里用的是匿名函数,因此ch可以直接使用,如果不用匿名函数,可以将ch作为参数传递,能起到相同的效果。
	go func() {
		ch <- searchText(query)
	}()
	go func() {
		ch <- searchImage(query)
	}()
	go func() {
		ch <- searchVideo(query)
	}()
	// 使用context包中的WithTimeout方法生成一个定时器,因为这里固定为最多5ms,所以第二个返回值省略了
	ctx, _ = context.WithTimeout(ctx, 5 * time.Millisecond)
	for {
		select {
			// 超过5ms,就会退出
			case <- ctx.Done():
				fmt.Println("时间到")
				return result
			// 某个函数返回后,就会触发,然后将结果添加到result中
			case val := <- ch:
				result = append(result, val)
		// 可以实现提前退出,因为如果三个函数均在5ms内返回,那么该程序不必非要等待5ms才退出
		default:
			if len(result) == 3 {
				fmt.Println("执行完毕")
				return result
			}
		}
	}
}
func main() {
	res := Search(context.Background(), "hello")
	fmt.Println(res)
}

       程序执行后,多次执行会看到不同的结果。

文中都是我个人的理解,如有错误的地方欢迎下方评论告诉我,我及时更正,大家共同进步

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值