前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Go 语言社区】关于select和channel数组的配合使用--转

【Go 语言社区】关于select和channel数组的配合使用--转

作者头像
李海彬
发布2018-03-19 17:58:09
2.9K0
发布2018-03-19 17:58:09
举报
文章被收录于专栏:Golang语言社区Golang语言社区
代码语言:javascript
复制
package main
import (
    "fmt"
    "math/rand"
    "reflect"
    "time"
)
type (
    product struct {
        id  int // 生产者序号
        val int // 产品
    }
    producer struct {
        id   int // 序号
        chnl chan *product
    }
)
var (
    producerList []*producer
    notifynew    chan int
    updatedone   chan int
)
func main() {
    rand.Seed(time.Now().Unix())
    notifynew = make(chan int, 1)
    updatedone = make(chan int, 1)
    ticker := time.NewTicker(time.Second)
    cases := update(ticker)
    for {
        chose, value, _ := reflect.Select(cases)
        switch chose {
        case 0: // 有新的生产者
            cases = update(ticker)
            updatedone <- 1
        case 1:
            // 创建新的生产者
            if len(producerList) < 5 {
                go newproducer()
            }
        default:
            item := value.Interface().(*product)
            fmt.Printf("消费: 值=%d 生产者=%d\n", item.val, item.id)
        }
    }
}
func update(ticker *time.Ticker) (cases []reflect.SelectCase) {
    // 新生产者通知
    selectcase := reflect.SelectCase{
        Dir:  reflect.SelectRecv,
        Chan: reflect.ValueOf(notifynew),
    }
    cases = append(cases, selectcase)
    // 定时器
    selectcase = reflect.SelectCase{
        Dir:  reflect.SelectRecv,
        Chan: reflect.ValueOf(ticker.C),
    }
    cases = append(cases, selectcase)
    // 每个生产者
    for _, item := range producerList {
        selectcase = reflect.SelectCase{
            Dir:  reflect.SelectRecv,
            Chan: reflect.ValueOf(item.chnl),
        }
        cases = append(cases, selectcase)
    }
    return
}
func newproducer() {
    newitem := &producer{
        id:   len(producerList) + 1,
        chnl: make(chan *product, 100),
    }
    producerList = append(producerList, newitem)
    notifynew <- 1
    <-updatedone
    go newitem.run()
}
func (this *producer) run() {
    for {
        time.Sleep(time.Duration(int(time.Millisecond) * (rand.Intn(1000) + 1)))
        item := &product{
            id:  this.id,
            val: rand.Intn(1000),
        }
        fmt.Printf("生产: 值=%d 生产者=%d\n", item.val, item.id)
        this.chnl <- item
    }
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-01-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档