Concurrency in Go: A Call Center Tutorial

43 views
Skip to first unread message

oldman

unread,
Jan 10, 2011, 1:23:02 AM1/10/11
to golang-china
讲channel 和 Goroutine的一篇blog(应该不用翻墙)
http://www.mprescient.com/journal/2011/1/9/concurrency-in-go-a-call-center-tutorial.html

chai

unread,
Jan 10, 2011, 1:29:33 AM1/10/11
to golang...@googlegroups.com
确实不要翻墙 :)


在 2011年1月10日 下午2:23,oldman <fenghaun...@gmail.com>写道:
讲channel 和 Goroutine的一篇blog(应该不用翻墙)
http://www.mprescient.com/journal/2011/1/9/concurrency-in-go-a-call-center-tutorial.html



--
chaishushan

oldman

unread,
Jan 11, 2011, 11:47:44 AM1/11/11
to golang...@googlegroups.com
今天又仔细看了下这篇blog,感觉博文下面的评论也蛮不错的,按照 Jesper Louis Andersen 的思路我重新写了一遍,附在下面,有啥问题欢迎指正。
PS 1:当然如果是队列实现,这篇文章的代码就基本足矣了
PS 2:这个Thread的第一封邮件少了“应用”,应该为“讲channel 和 Goroutine应用的一篇blog

package main
 
import (
    "fmt"
    "time"
    "rand"
)
 
type Call struct {
    id         int
    duration   int
    start_time int64
    end        chan bool
}
 
func (c *Call) Wait() {
    <-c.end
}
 
type Agent struct {
    id int
    cc *CallCenter
}
 
func (ag *Agent) Run(c *Call) {
    fmt.Printf("Agent: %d, answering Call: %d\n", ag.id, c.id)
    time.Sleep(int64(c.duration * 1000000))
    fmt.Printf("Call %d answered; waited %d milliseconds\n", c.id, (time.Nanoseconds()-c.start_time)/1000000)
}
 
func (ag *Agent) Becomeidle(cc *CallCenter) {
    cc.idleagents <- ag
}
 
type CallCenter struct {
    allagents  []Agent
    idleagents chan *Agent
}
 
func (cc *CallCenter) Open(agentnum int) {
    fmt.Println("Call center opening")
    cc.allagents = make([]Agent, agentnum)
    cc.idleagents = make(chan *Agent, agentnum)
    for _, ag := range cc.allagents {
        (&ag).Becomeidle(cc)
    }
    fmt.Println("Call center open")
}
 
func (cc *CallCenter) Close() {
    fmt.Println("Call center closing")
    close(cc.idleagents)
    fmt.Println("Call center closed")
}
 
func handle(cc *CallCenter, c *Call) {
    ag := <-cc.idleagents
    ag.Run(c)
    ag.Becomeidle(cc)
    c.end <- true
}
 
func elapse(tip string, begin int64) {
    end := time.Nanoseconds()
    fmt.Printf("%s: %d seconds\n", tip, (end-begin)/1000000000)
}
 
func main() {
    num_agents := 1
    num_calls := 10
    max_dur := 5
    call_center := new(CallCenter)
 
    defer elapse("All Time", time.Nanoseconds())
 
    call_center.Open(num_agents)
    allc := make([]*Call, num_calls)
    for i := 0; i < num_calls; i++ {
        allc[i] = &Call{i, rand.Int() * max_dur, time.Nanoseconds(), make(chan bool)}
    }
 
    for _, c := range allc {
        go handle(call_center, c)
    }
 
    for _, c := range allc {
        c.Wait()
    }
    call_center.Close()
}

2011/1/10 chai <chais...@gmail.com>

oldman

unread,
Jan 11, 2011, 11:56:17 AM1/11/11
to golang...@googlegroups.com
呃。。。排版有点问题,附纯文本版本吧
2011/1/12 oldman <fenghaun...@gmail.com>
Reply all
Reply to author
Forward
0 new messages