L'instruction select est une instruction spéciale qui ne peut être utilisée que pour les opérations d'envoi et de réception de canal
L'exécution d'une instruction select sélectionnera l'une des branches à exécuter.
L'instruction select est similaire à l'instruction switch, mais la méthode de sélection d'une branche est différente.
Chaque branche commence par le mot-clé case.
Après chaque cas, il ne peut être envoyé ou reçu que pour un certain canal.
Le côté droit de la sélection suit directement l'accolade gauche.
L'instruction select est une instruction spéciale qui ne peut être utilisée que pour les opérations d'envoi et de réception de canal.
L'exécution d'une instruction select sélectionnera l'une des branches à exécuter.
L'instruction select est différente de l'instruction switch, mais la méthode de sélection d'une branche est différente.
Chaque branche commence par le mot-clé case.
Après chaque cas, il ne peut être envoyé ou reçu que pour un certain canal.
Le côté droit de la sélection suit directement l'accolade gauche.
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。
Exemples:
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{[]int{10, 48}, []int{26, 97}, []int{26, 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
}