Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.3k views
in Technique[技术] by (71.8m points)

go的线程在实际中的实践?

比如获取游戏信息的接口,除了基本的游戏信息之外一同返回额外的信息:评论,关联的文章,算法推荐。

{
    "game_basic":{

    },
    "game_article":{

    },
    "game_suggestion":{
        
    }
}

每一个都需要涉及对应的数据库查询,以前是线性的查询,一个查完再查另一个。如何使用Goroutine或者通道或者context进行,将额外的信息可以通过Goroutine获取。

  1. 需要对所有的额外设置统一的超时时间
  2. 外部能够取消新开的Goroutine
  3. 查询并不是一个循环执行的操作,本身就是一个耗时操作,怎么取消这个部分
  4. 怎么更好的获取额外的信息,每一个定义一个通道太繁复了

我目前的想法是这样,性能或者内存有影响么。还需要解决不超时更快的情况

func GetGame() {
    gameCh := make(chan interface{})
    ctx, _ := context.WithTimeout(context.Background(), time.Second*1)

    go GetGameArticle(gameCh)
    go GetGameComment(gameCh)

    game := bson.M{}

    for {
        select {
        case extra := <-gameCh:
            game["article"] = extra
        case <-ctx.Done():
            goto DONE
        }
    }
DONE:

    fmt.Println(game)
}

func GetGameArticle(ch chan interface{}) {
    ch <- "666666666666"
}

func GetGameComment(ch chan interface{}) {
    ch <- "99999999999"
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

取消一个没有循环的goroutine没想到好方法。查询数据库时也设置一个超时,避免泄露就好了吧。

第四个问题:GetGameArticle这种获取部分信息的函数里是不是可以直接反序列化game的一部分内容。就不用考虑chan发送出来的字符串应该放在那里了。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...