GO基础(二)

本例中梳理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
", i)
        in <- i
    }
}

func func04(in chan int) {
    for {
        fmt.Printf("Receive Msg:%d
", <-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
}
原文地址:https://www.cnblogs.com/Fredric-2013/p/5980109.html