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终于迎来了久 ...
随机推荐
- MySQL 命令总结
MySQL命令总结 1.数据库操作 查看在当前服务器中有多少个数据库 创建数据库 >CREATE DATABASE db_name DEFAULT CHARACTER SET utf8 COLL ...
- Codeforces 420D Cup Trick 平衡树
Cup Trick 平衡树维护一下位置. #include<bits/stdc++.h> #include <bits/extc++.h> #define LL long lo ...
- 完成将 toChineseNum, 可以将数字转换成中文大写的表示,处理到万级别,例如 toChineseNum(12345),返回 一万二千三百四十五
const toChineseNum = (num) => { const unit = ['', '十', '百', '千'] const counts = ['零', '一', '二', ' ...
- BZOJ3230 相似子串 字符串 SA ST表
原文链接http://www.cnblogs.com/zhouzhendong/p/9033092.html 题目传送门 - BZOJ3230 题意 给定字符串$s$.长度为$n$. 现在有$Q$组询 ...
- BZOJ1396 识别子串 字符串 SAM 线段树
原文链接http://www.cnblogs.com/zhouzhendong/p/9004467.html 题目传送门 - BZOJ1396 题意 给定一个字符串$s$,$|s|\leq 10^5$ ...
- VMware下centos7安装
VMware下centos7安装 转载地址:https://blog.csdn.net/hui_2016/article/details/68927487 一. 软件准备 二. Vmware12安装 ...
- linux(manjaro)磁盘迁移/opt /home
目录 1. 创建临时挂载点/opt, 并将分区挂载到临时挂载点上: 2. 切换单用户,将除了root用户之外的用户踢出 3. 将/opt目录下的所有内容拷贝到临时挂载点中,等待结束 4. 进入/et ...
- P2661 信息传递
P2661 信息传递dfs求最小环,要加时间戳,记录这个点是哪一次被dfs到的.] #include<iostream> #include<cstdio> #include&l ...
- Mybatis之注解实现动态sql
通过注解实现动态sql一共需要三部:1.创建表,2.创建entity类,3.创建mapper类, 4.创建动态sql的Provider类.1.和2.可以参见该系列其他文章,这里主要对3和4进行演示,并 ...
- SpringBoot的国际化使用
在项目中,很多时候需要国际化的支持,这篇文章要介绍一下springboot项目中国际化的使用. 在这个项目中前端页面使用的thymeleaf,另外加入了nekohtml去掉html严格校验,如果不了解 ...