Utilisation de chan et traitement sélectif et parallèle de plusieurs chan

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
}

 

A publié 127 articles originaux · Aime 24 · Visites 130 000+

Je suppose que tu aimes

Origine blog.csdn.net/Linzhongyilisha/article/details/104297813
conseillé
Classement