一直想写一个无锁队列,为了提高项目的背景效率。

有机会看到linux核心kfifo.h 原则。

所以这个实现自己仿照,眼下linux我们应该能够提供外部接口。

#ifndef _NO_LOCK_QUEUE_H_
#define _NO_LOCK_QUEUE_H_ #include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <pthread.h>
#include <iostream>
using namespace std; #ifndef max
#define max(x, y) ({ \
typeof(x) _max1 = (x); \
typeof(y) _max2 = (y); \
(void) (&_max1 == &_max2); \
_max1 > _max2 ? _max1 : _max2; })
#endif #ifndef min
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
#endif class Kfifo
{
public:
Kfifo(unsigned int isize);
~Kfifo();
unsigned int get(unsigned char *buffer, unsigned int len);
unsigned int put(const unsigned char *buffer, unsigned int len);
static unsigned long roundup_power_of_two(unsigned long val);
private:
inline bool is_power_of_2(unsigned long n)
{
return (n != 0 && ((n & (n - 1)) == 0));
};
inline unsigned int unused()
{
return (mask + 1) - (in - out);
} private:
unsigned int size;
unsigned int in;
unsigned int out;
unsigned int mask;
unsigned char* buffer;
}; struct proto
{
unsigned int msgid;
unsigned int cmd;
unsigned int info;
proto():msgid(0),cmd(0),info(0){}
}; #endif

实现文件

#include "MKfifo.h"

Kfifo::~Kfifo()
{
if (buffer) free(buffer);
size = in = out=0;
}
unsigned long Kfifo::roundup_power_of_two(unsigned long val)
{
if (val & (val-1) == 0)
{
return val;
}
unsigned long maxulong = (unsigned long )((unsigned long ) ~0);
unsigned long andv = ~(maxulong&(maxulong>>1));
while((andv & val) == 0)
andv = andv>>1;
return andv<<1;
}
Kfifo::Kfifo(unsigned int isize):size(isize),in(0),out(0),mask(size - 1)
{
if (!is_power_of_2(isize))
{
size = roundup_power_of_two(isize);
}
buffer =(unsigned char*) malloc(isize);
} unsigned int Kfifo::get(unsigned char *_buffer, unsigned int len)
{
unsigned int l;
len = min(len, in - out);
__sync_synchronize(); l = min(len,size -(out&(size-1)));
memcpy(_buffer,buffer + (out& (size-1)),l);
memcpy(_buffer + l,buffer,len - l); __sync_synchronize(); out +=len;
return len; }
unsigned int Kfifo::put(const unsigned char *_buffer, unsigned int len)
{
unsigned int l;
len = min(len, size - in + out);
__sync_synchronize();
l = min(len, size - (in & (size - 1)));
memcpy(buffer + (in & (size - 1)), _buffer, l);
memcpy(buffer, _buffer + l, len - l);
__sync_synchronize();
in += len;
return len; } void * consumer(void * arg)
{
printf("consumer\n");
Kfifo* fifo = (Kfifo*) arg;
if (!fifo)
{
return NULL;
} for (;;)
{
proto p;
unsigned int len = fifo->get((unsigned char*)&p,sizeof(p));
if (len>0)
{
cout << "~~~~~~~~~~~~~~~~~~~~"<<endl;
cout << "consumer proto msg id :"<<p.msgid<<endl;
cout << "consumer proto msg cmd :"<<p.cmd<<endl;
cout << "consumer proto msg info :"<<p.info<<endl;
cout << "~~~~~~~~~~~~~~~~~~~~"<<endl;
}
} return (void *)fifo;
}
void* producer(void* args)
{
Kfifo* fifo = (Kfifo*) args; if (!fifo)
{
return NULL;
}
unsigned int i=0;
for (;;)
{
proto p;
p.msgid = i++;
p.cmd = 333;
p.info = 44444;
fifo->put((const unsigned char*)&p,sizeof(p));
cout<<"producer put msgid :"<<p.msgid<<endl;
}
return (void*)fifo;
}
int main()
{
Kfifo *fifo = new Kfifo(1024);
pthread_t consumeid,producerid;
pthread_create(&producerid,NULL,producer,(void*)fifo);
pthread_create(&consumeid,NULL,consumer,(void*)fifo); printf("info!!\n");
pthread_join(consumeid,NULL);
pthread_join(producerid,NULL);
return 0;
}

可经过测试。我将基于队列。其丰富的应用。

无锁队列--基于linuxkfifo实现的更多相关文章

  1. 基于无锁队列和c++11的高性能线程池

    基于无锁队列和c++11的高性能线程池线程使用c++11库和线程池之间的消息通讯使用一个简单的无锁消息队列适用于linux平台,gcc 4.6以上   标签: <无>   代码片段(6)[ ...

  2. 基于folly的AtomicIntrusiveLinkedList无锁队列进行简单封装的多生产多消费模型

    1.基于folly的AtomicIntrusiveLinkedList略微修改的无锁队列代码: #ifndef FOLLY_REVISE_H #define FOLLY_REVISE_H namesp ...

  3. boost 无锁队列

    一哥们翻译的boost的无锁队列的官方文档 原文地址:http://blog.csdn.net/great3779/article/details/8765103 Boost_1_53_0终于迎来了久 ...

  4. 一个可无限伸缩且无ABA问题的无锁队列

    关于无锁队列,详细的介绍请参考陈硕先生的<无锁队列的实现>一文.然进一步,如何实现一个不限node数目即能够无限伸缩的无锁队列,即是本文的要旨. 无锁队列有两种实现形式,分别是数组与链表. ...

  5. folly无锁队列,尝试添加新的函数(续)

    基于上一篇文章,dropHead取出节点后,删除节点,会出现内存访问的问题.按照这个逻辑,如果将移出的节点保存到一个无锁队列中,然后在需要节点的时候,从这个备用的无锁队列中取出节点,那么应该就可以避开 ...

  6. DIOCP开源项目-高效稳定的服务端解决方案(DIOCP + 无锁队列 + ZeroMQ + QWorkers) 出炉了

    [概述] 自从上次发布了[DIOCP开源项目-利用队列+0MQ+多进程逻辑处理,搭建稳定,高效,分布式的服务端]文章后,得到了很多朋友的支持和肯定.这加大了我的开发动力,经过几个晚上的熬夜,终于在昨天 ...

  7. 高性能无锁队列 Disruptor 初体验

    原文地址: haifeiWu和他朋友们的博客 博客地址:www.hchstudio.cn 欢迎转载,转载请注明作者及出处,谢谢! 最近一直在研究队列的一些问题,今天楼主要分享一个高性能的队列 Disr ...

  8. 锁、CAS操作和无锁队列的实现

    https://blog.csdn.net/yishizuofei/article/details/78353722 锁的机制 锁和人很像,有的人乐观,总会想到好的一方面,所以只要越努力,就会越幸运: ...

  9. 【DPDK】【ring】从DPDK的ring来看无锁队列的实现

    [前言] 队列是众多数据结构中最常见的一种之一.曾经有人和我说过这么一句话,叫做“程序等于数据结构+算法”.因此在设计模块.写代码时,队列常常作为一个很常见的结构出现在模块设计中.DPDK不仅是一个加 ...

随机推荐

  1. 严重: Servlet.service() for servlet jsp threw exception java.lang.IllegalStateException: getOutputStream() has already been called

    错误: 严重: Servlet.service() for servlet jsp threw exception java.lang.IllegalStateException: getOutput ...

  2. [C++Boost]程序参数项解析库Program_options使用指南

    介绍 程序参数项(program options)是一系列name=value对,program_options 允许程序开发者获得通过命令行(command line)和配置文件(config fi ...

  3. [置顶] Guava学习之Iterators

    Iterators类提供了返回Iterator类型的对象或者对Iterator类型对象操作的方法.除了特别的说明,Iterators类中所有的方法都在Iterables类中有相应的基于Iterable ...

  4. 【floyd】HDU 1874 畅通project续

    之后的题解偏重有用/总结性质,尽量理解算法本身而不是题,时间复杂度什么的也能够放放. 非常久之前做过这个题,当时使用dijkstra做的,关于几个最短路算法,分类的话能够分为下面几种. 1.单源最短路 ...

  5. WCF技术剖析之十五:数据契约代理(DataContractSurrogate)在序列化中的作用

    原文:WCF技术剖析之十五:数据契约代理(DataContractSurrogate)在序列化中的作用 [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经> ...

  6. HDU ACM 1098 Ignatius&#39;s puzzle

    分析:裴蜀定理,a,b互质的充要条件是存在整数x,y使ax+by=1.存在整数x,y,使得ax+by=c.那么c就是a,b的公约数. 如果存在数a ,由于对随意x方程都成立.则有当x=1时f(x)=1 ...

  7. Eclipse用法和技巧四:生成说明文档1

    写代码经常要添加注释的,java代码的注释也可以分为两种.单行注释以“//”作为开头就可以.段落注释在第一行开头添加“/*”,在最后一行结尾添加“*/"即可.这里介绍一种添加注释的方法,其注 ...

  8. 重操JS旧业第六弹:基本类型包装

    在前面已经知道js中的类型有boolean,string,number,undefined,function,object,其中boolean,number,string为值类型.所谓的基本类型包装, ...

  9. 14.10.2 File Space Management 文件空间管理:

    14.10.2 File Space Management 文件空间管理: 数据文件 你定义在配置文件形成了InnoDB的系统表空间, 文件是逻辑连接形成表空间,没有条带化使用. 你不能定义你的表在表 ...

  10. socket为send和recv设置超时时间

    linux和windows下用setsockopt设置SO_SNDTIMEO,SO_RCVTIMEO的参数的一点区别 UDP的socket在某些情况:如对方关闭时,本地可能sendto不出去数据,然后 ...