1月 28

golang用 channel简单高效队列

需求为先进先出原则,批量取出的缓存队列。要求比较简单,尝试开源queue代码,在压力大的情况下可能崩溃。使用redis做队列,CPU使用总量增长一倍多,IO开销也不小。最后用golang自带的channel,可以实现,简单高效,资源消耗也不大。

package main

import (
	"log"
	"os"
	"strconv"
	"time"
)

// 公共通道
// 通道数要比缓存最高数量大,以保证读取慢的情况下不会溢出
var Ch = make(chan string, 100000)

func wch(num int) {
	// 写入
	func() {
		if vv := recover(); vv != nil {
			os.Exit(0)
		}
	}()
	ws := strconv.Itoa(num)
	Ch <- ws
}

func rch() {
	// 读取
	var rs string
	for {
		select {
		case rs = <-Ch:
			log.Printf("read %v\n", rs)
		default:
			log.Printf("empty")
			return
		}
		if len(Ch) <= 0 {
			return
		}
		//Chsync.Done()
	}
}

func main() {
	var i int
	for i = 0; i < 200000; i++ {
		wch(i)
		if i%1000 == 0 {
			go rch()
			//Chsync.Add(1)
		}
	}
	time.Sleep(time.Millisecond * 6000)
	//Chsync.Wait()
	log.Printf("have %v", len(Ch))
}