本例中梳理go语言中的协程和通道。
package main import ( "fmt" "time" ) //func01、func02 为演示同步机制 func func01(in chan int) { fmt.Println("func01 in") in <- 2 fmt.Println("func01 out") } func func02(in chan int) { fmt.Println("func02 in") out := <-in fmt.Println(out) fmt.Println("func02 out") } //func03, func04 为演示消息传输机制 func func03(in chan int) { for i := 0; i < 4; i++ { fmt.Printf("Send Msg:%d\n", i) in <- i } } func func04(in chan int) { for { fmt.Printf("Receive Msg:%d\n", <-in) } } func main() { /*通道是协程之间的数据传输通道,类似操作系统中采用管道进行进程间通信 协程向通道写入数据,如果通道满,挂起协程,知道队列中空出 协程向通道读取数据,如果无数据,挂起协程,直到有数据。*/ //10为channel的可选参数,默认是0,表示channel的缓冲区 //为0时成为无缓冲channel,用来做同步 ch := make(chan int) ch2 := make(chan int, 1) /* * 同步机制,打印结果为: * func02 in * func01 in * func01 out * 2 * func02 out * main end */ //go func02(ch) //go func01(ch) /* * 消息交互,打印结果为: * Send Msg:0 * Send Msg:1 * Send Msg:2 * Receive Msg:0 * Receive Msg:1 * Receive Msg:2 * Send Msg:3 * Receive Msg:3 * main end * 一次性能发送几条消息,取决于定义channel时设置的 * 缓冲区大小 */ go func03(ch2) go func04(ch2) time.Sleep(1e9) fmt.Println("main end") close(ch) }
在实际项目中,我们可以通过定义一个全局的channel map来维护多通道的数据传输,例如:
var MsgQuene quene type MsgQuene struct { chans map[uint8]chan string } //初始化消息队列 func (q *MsgQuene) Init() { q.chans = make(map[uint8]chan string) } //为某一个消息通道,增加对应的channel func (q *MsgQuene) addQuene(id uint8) { q.chans[id] = make(chan string) } //为某一个消息通道,删除对应的channel func (q *MsgQuene) deleteQuene(id uint8) { delete(q.chans, id) } //从指定消息通道中读取数据 func (q *MsgQuene) Get(id uint8) string { return <-q.chans[id] } //从指定消息通道中写入数据 func (q *MsgQuene) Put(id uint8, s string) { q.chans[id] <- s }
时间: 2024-10-12 12:56:08