chan与select的使用及多个chan的并行处理
Posted siwluxuefeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了chan与select的使用及多个chan的并行处理相关的知识,希望对你有一定的参考价值。
select语句是一种仅能用于通道发送和接收操作的专用语句
一条select语句的执行,会选择其中某一个分支执行。
select语句与switch语句类似,但选择分支的方法不同。
每个分支以关键字case开始。
每个case后只能是针对某个通道的发送语句或接收语句。
select右边直接跟左花括号。
select语句是一种仅能用于通道发送和接收操作的专用语句
一条select语句的执行,会选择其中某一个分支执行。
select语句与switch语句类型,但选择分支的方法不同。
每个分支以关键字case开始。
每个case后只能是针对某个通道的发送语句或接收语句。
select右边直接跟左花括号。
var intChan = make(chan int, 10)
var strChan = make(chan string, 10)
select
case e1 := <-intChan:
fmt.Printf("The 1th case was seleced. e1=%v.\\n",e1)
case e2 := <-strChan:
fmt.Println("The 2nd case was selectd.e2=%v.\\n",e2)
default:
fmt.Println("Default)
select中多个case,但并不会并行处理。
假如3个channel, select每次只能选择1个(对应ReqHandle1),当进入第一个case处理时,剩下的所有case都只能等待第一个case处理完后,才有可能进入。
假如3个channel需要同时处理,目前我是起了3个goroutine(对应ReqHandle2),每个goroutine处理一个chan。
示例:
package main
import (
"fmt"
"math/rand"
"time"
)
var ChanReq0 = make(chan interface, 100)
var ChanReq1 = make(chan interface, 100)
var ChanReq2 = make(chan interface, 100)
func main()
ReqPush()
//test case1
//go ReqHandle1()
//test case2
go ReqHandle2()
//
for i := 0; i < 1000; i++
time.Sleep(time.Second)
fmt.Println(time.Now())
time.Sleep(10 * time.Minute)
func ReqPush()
for i := 0; i < 100; i++
ChanReq0 <- string(Krand(16, KC_RAND_KIND_LOWER))
ChanReq1 <- string(Krand(16, KC_RAND_KIND_NUM))
ChanReq2 <- string(Krand(16, KC_RAND_KIND_UPPER))
/*
select中多个case,但并不会并行处理,
如:进入第一个case等待处理时,剩下的所有case都只能等待第一个case处理完后,才有可能进入。
*/
func ReqHandle1()
for
select
case req0 := <-ChanReq0:
//do something
time.Sleep(10 * time.Second)
fmt.Println("Chan0 pop:", req0)
case req1 := <-ChanReq1:
//do something
time.Sleep(5 * time.Second)
fmt.Println("Chan1 pop:", req1)
case req2 := <-ChanReq2:
//do something
time.Sleep(1 * time.Second)
fmt.Println("Chan2 pop:", req2)
/*
3个Chan,每个Chan起一个Chan起一个goroutine处理
*/
func ReqHandle2()
go func()
for
req := <-ChanReq0
time.Sleep(10 * time.Second)
fmt.Println("Chan0 pop:", req)
//db :=
()
fmt.Println("xx1")
go func()
for
req := <-ChanReq1
time.Sleep(5 * time.Second)
fmt.Println("Chan1 pop:", req)
//db :=
()
fmt.Println("xx2")
go func()
for
req := <-ChanReq2
time.Sleep(1 * time.Second)
fmt.Println("Chan2 pop:", req)
//db :=
()
const (
KC_RAND_KIND_NUM = 0 // 纯数字
KC_RAND_KIND_LOWER = 1 // 小写字母
KC_RAND_KIND_UPPER = 2 // 大写字母
KC_RAND_KIND_ALL = 3 // 数字、大小写字母
)
// 随机字符串
func Krand(size int, kind int) []byte
ikind, kinds, result := kind, [][]int[]int10, 48, []int26, 97, []int26, 65, make([]byte, size)
is_all := kind > 2 || kind < 0
rand.Seed(time.Now().UnixNano())
for i := 0; i < size; i++
if is_all // random ikind
ikind = rand.Intn(3)
scope, base := kinds[ikind][0], kinds[ikind][1]
result[i] = uint8(base + rand.Intn(scope))
return result
以上是关于chan与select的使用及多个chan的并行处理的主要内容,如果未能解决你的问题,请参考以下文章
Go语言无锁队列组件的实现 (chan/interface/select)