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)
}
}
}
Go语言无锁队列组件的实现 (chan/interface/select)的更多相关文章
- Erlang运行时中的无锁队列及其在异步线程中的应用
本文首先介绍 Erlang 运行时中需要使用无锁队列的场合,然后介绍无锁队列的基本原理及会遇到的问题,接下来介绍 Erlang 运行时中如何通过“线程进度”机制解决无锁队列的问题,并介绍 Erlang ...
- 【DPDK】【ring】从DPDK的ring来看无锁队列的实现
[前言] 队列是众多数据结构中最常见的一种之一.曾经有人和我说过这么一句话,叫做“程序等于数据结构+算法”.因此在设计模块.写代码时,队列常常作为一个很常见的结构出现在模块设计中.DPDK不仅是一个加 ...
- 无锁队列以及ABA问题
队列是我们非常常用的数据结构,用来提供数据的写入和读取功能,而且通常在不同线程之间作为数据通信的桥梁.不过在将无锁队列的算法之前,需要先了解一下CAS(compare and swap)的原理.由于多 ...
- CAS简介和无锁队列的实现
Q:CAS的实现 A:gcc提供了两个函数 bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...)// ...
- java轻松实现无锁队列
1.什么是无锁(Lock-Free)编程 当谈及 Lock-Free 编程时,我们常将其概念与 Mutex(互斥) 或 Lock(锁) 联系在一起,描述要在编程中尽量少使用这些锁结构,降低线程间互相阻 ...
- 锁、CAS操作和无锁队列的实现
https://blog.csdn.net/yishizuofei/article/details/78353722 锁的机制 锁和人很像,有的人乐观,总会想到好的一方面,所以只要越努力,就会越幸运: ...
- HashMap的原理与实 无锁队列的实现Java HashMap的死循环 red black tree
http://www.cnblogs.com/fornever/archive/2011/12/02/2270692.html https://zh.wikipedia.org/wiki/%E7%BA ...
- zeromq源码分析笔记之无锁队列ypipe_t(3)
在上一篇中说到了mailbox_t的底层实际上使用了管道ypipe_t来存储命令.而ypipe_t实质上是一个无锁队列,其底层使用了yqueue_t队列,ypipe_t是对yueue_t的再包装,所以 ...
- boost 无锁队列
一哥们翻译的boost的无锁队列的官方文档 原文地址:http://blog.csdn.net/great3779/article/details/8765103 Boost_1_53_0终于迎来了久 ...
随机推荐
- lvs-dr
第5节 dr模型 在rs上配置 :rip 和vip vip定义在lo别名上 Director 上配置:vip 和dip 都只需要一块网卡 网卡都桥接 Vip: 192.168.0.105 ...
- 51Nod1773 A国的贸易 多项式 FWT
原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1773.html 题目传送门 - 51Nod1773 题意 给定一个长度为 $2^n$ 的序列,第 $ ...
- java06作业归档
动手动脑 阅读QiPan.java示例程序了解如何利用二维数组和循环语句绘制五子棋盘. package 归档作业6; import java.io.*; public class QIPAN { // ...
- Raspberry 音乐播放器omxplayer安装
首先需要安装的是omxplayer播放器的依赖的库文件: wget http://pexpect.sourceforge.net/pexpect-2.3.tar.gz tar xzf pexpect- ...
- Zookeeper的概述、安装部署及选举机制
一.Zookeeper概述 1.Zookeeper是Hadoop生态的管理者,它致力于开发和维护开源服务器,实现高度可靠的分布式协调. 2.Zookeeper的两大功能: (1)存储数据 (2)监听 ...
- Manjaro安装配置笔记
简单介绍: Manjaro和Ubuntu的都使用有段时间了,还是AUR大法用着舒服趁着由KDE桌面更换deepin时系统崩溃,直接重装了系统,版本:Manjaro-deepin-17.1.7-x86_ ...
- flex 布局的复习
- PAT (Advanced Level) Practise 1004 解题报告
GitHub markdownPDF 问题描述 解题思路 代码 提交记录 问题描述 Counting Leaves (30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 1600 ...
- os模块、os.path模块、shutil模块、configparser模块、subprocess模块
一.os模块 os指的是操作系统 该模块主要用于处理与操作系统相关的操作,常用的是文件操作(读.写.删.复制.重命名). os.getcwd() 获取当前文件所在的文件夹路径 os.chdir() ...
- Redis自学笔记:3.1入门-热身
第3章:入门 3.1热身 获取符合规则的键名列表:keys 匹配key 表3-1 glob风格通配符规则 符号 含义 ? 匹配一个字符 * 匹配任意个(包括0个)字符 [ ] 匹配括号间的任一字符,可 ...