Use of chan and select and parallel processing of multiple chan

The select statement is a special statement that can only be used for channel sending and receiving operations

The execution of a select statement will select one of the branches to execute.

The select statement is similar to the switch statement, but the method of selecting a branch is different.

Each branch starts with the keyword case.

After each case, it can only be sent or received for a certain channel.

The right side of select directly follows the left brace.

The select statement is a special statement that can only be used for channel sending and receiving operations.
The execution of a select statement will select one of the branches to execute.
The select statement is different from the switch statement, but the method of selecting a branch is different.

Each branch starts with the keyword case.
After each case, it can only be sent or received for a certain channel.
The right side of select directly follows the left brace.


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。

Examples:

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
}

 

Published 127 original articles · Likes 24 · Visits 130,000+

Guess you like

Origin blog.csdn.net/Linzhongyilisha/article/details/104297813