Go语言无锁队列组件的实现 (chan/interface/select)

1. 背景

go代码中要实现异步很简单,go funcName()。
但是进程需要控制协程数量在合理范围内,对应大批量任务可以使用“协程池 + 无锁队列”实现。

2. golang无锁队列实现思路

  • Channel是Go中的一个核心类型,你可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯(communication)。无锁队列使用带buff的chan存储数据。
  • interface{} (类似c++的void*, java的Object)可以与任意类型互转。无锁队列使用interface{}作为数据存储类型。
  • select可以处理多个信号, 可以用来解决channel阻塞问题。

3. 代码实现

package main

import (
	"fmt"
	"time"
)

type DataContainer struct {
	Queue chan interface{}
}

func NewDataContainer(max_queue_len int) (dc *DataContainer){
	dc = &DataContainer{}
	dc.Queue = make(chan interface{}, max_queue_len)
	return dc
}

//非阻塞push
func (dc *DataContainer) Push(data interface{}, waittime time.Duration) bool{
	click := time.After(waittime)
	select {
	case dc.Queue <- data:
		return true
	case <- click:
		return false
	}
}

//非阻塞pop
func (dc *DataContainer) Pop(waittime time.Duration) (data interface{}){
	click := time.After(waittime)
	select {
	case data =<-dc.Queue:
		return data
	case <- click:
		return nil
	}
}

//test
var MAX_WAIT_TIME = 10 *time.Millisecond
func main(){
	type dataItem struct {
		name string
		age int
	}

	datacotainer := NewDataContainer(2)
	//add
	fmt.Printf("res=%v\n", datacotainer.Push(&dataItem{"zhangsan",25}, MAX_WAIT_TIME))
	fmt.Printf("res=%v\n", datacotainer.Push(&dataItem{"lisi",30}, MAX_WAIT_TIME))
	fmt.Printf("res=%v\n", datacotainer.Push(&dataItem{"wangwu",28}, MAX_WAIT_TIME))

	//get
	var item interface{}
	item = datacotainer.Pop(MAX_WAIT_TIME)
	if item != nil{
		if tmp,ok := item.(*dataItem); ok{	//interface转为具体类型
			fmt.Printf("item name:%v, age:%v\n", tmp.name, tmp.age)
		}
	}
}

posted on   旭东的博客  阅读(6325)  评论(1编辑  收藏  举报

编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示