IOKING真正无锁服务器引擎之消息引擎模块Demo(no-lock)



关键词:

no-lock interlocked lock-free tcp/ip socket server engine epoll iocp server out-of-orderexecution无锁 原子锁 原子操作 原子指令 锁无关 开放锁 通讯服务器 引擎 高并发 大数据 搜索引擎 完成端口服务器 cpu乱序并行执行 内存栅栏

IOKING 真正无锁服务器引擎之消息引擎模块Demo(no-lock)

这是继无锁iocp通讯模块以后,又一个无锁模块。下一步有时间将会把两个整合在一起。

先给本文无锁下个定义吧,无锁:在非内核态、非CPU原子操作指令(包括不使用内存栅栏)的情况下实现的线程间消息通讯的机制。

无锁关键问题:CPU乱序并行处理、MEM和CPU Cache不一致性

2015-8.27 更新版本:

下载链接(包含内核头文件和Demo的源码):http://download.csdn.net/detail/guestcode/9055835

实现了 linux和window跨平台

ubuntu64:

win32:

win64:

应用举例:

//创建引擎对象

CIokEngineTest *pIokEngine = new CIokEngineTest;

//创建生产者对象,nPTNum:生产者的线程数量

//CIokProducer *pProducer = new CIokProducer(pIokEngine, (char*)"Producer", nPTNum, 0);

//创建消费者对象,nCTNum:消费者的线程数量

CIokConsumer *pConsumer = new CIokConsumer(pIokEngine, (char*)"Consumer", nCTNum, 0);

//设置生产消费关系,默认队列容量10000000

pProducer->SetConsumer<CIokConsumer>(pConsumer, 10000000, 0);

//启动引擎

pIokEngine->Start(pProducer, pConsumer);

通过创建生产消费对象和设置生产消费关系,可实现如下或更复杂的软件内部架构:

//生产线程制造消息:

inline void CIokPThread::OnMsg(CIokMessage *pMessage)

{

DWORD dwTickCount = GetTickCount();

MadeMsg(dwTickCount, (void*)dwTickCount, dwTickCount, dwTickCount, (void*)dwTickCount, (void*)dwTickCount);

}

//消费线程消费消息:

inline void CIokCThread::OnMsg(CIokMessage *pMessage)

{

//计算消息传递时间

m_dwLong = GetTickCount() - (DWORD)pMessage->nMsg;

//判断收到的消息是否正确

m_nError += (pMessage->nMsg != (LONG_PTR)pMessage->nParam1)

|| (pMessage->nMsg != (LONG_PTR)pMessage->nParam2)

|| (pMessage->nMsg != (LONG_PTR)pMessage->pParam1)

|| (pMessage->nMsg != (LONG_PTR)pMessage->pParam2);

}

2015-8.27之前的:

Demo下载链接:

http://download.csdn.net/detail/guestcode/8579089

这是继无锁iocp通讯模块以后,又一个无锁模块。本来已经早已成型,一直没有理会太多。下一步有时间将会把两个整合在一起。

先给无锁定义吧,无锁:在非内核态、非CPU原子操作指令(包括不使用内存栅栏)的情况下实现的线程间消息通讯的机制(个人定义,并仅在本文有效)。

无锁关键是避免CPU乱序并行运行导致的数据错误,避免脏读情况。

这是无锁测试截图:

每秒1400万次消息传递,两个小时1000亿,内核使用率明显很低

这是iocp(实际是有锁的)消息通讯的截图:

每秒230万,也是相当不错了,不过内核高了。

以上是理想状态下的单纯消息通讯测试,不代表实际使用环境,难免有出入。至于安全性还有待以后有时间进一步测试。

欢迎共同探讨。

补充:

以下是经过API封装后的demo,多做了些事情,比如验证API参数的合法性、判断一个生产链上最上一个的队列是否空闲来决定是否休眠等待等。只需创建生产者、消费者线程及队列,设置队列的生产消费关系,即可组建成下列这样的程序架构(当然也可以形成一个闭环),而你要做的,仅仅需要在线程的OnMsg函数里面处理消息即可,这个过程不要关心多线的同步问题即可完成无锁消息传递,这是一个简易而又高效的基于消息传递机制的服务器程序架构引擎,保证了消息有序而又高效的被处理:

最终消费者<------队列<------消费者&生产者<------队列<------消费者&生产者<------队列<------起初生产者



版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-22 12:07:33

IOKING真正无锁服务器引擎之消息引擎模块Demo(no-lock)的相关文章

IOKING MsgEngine无锁消息引擎(no-lock)

 关键词: no-lock interlocked lock-free tcp/ip server engine iocp server out-of-orderexecution无锁 原子锁 原子操作 原子指令 锁无关 开放锁 通讯服务器 引擎 高并发 大数据 搜索引擎 完成端口服务器 cpu乱序并行执行 内存栅栏 Demo下载链接: http://download.csdn.net/detail/guestcode/8579089 这是继无锁iocp通讯模块以后,又一个无锁模块.本来已经

一个无锁消息队列引发的血案:怎样做一个真正的程序员?(二)——月:自旋锁

前续 一个无锁消息队列引发的血案:怎样做一个真正的程序员?(一)——地:起因 一个无锁消息队列引发的血案:怎样做一个真正的程序员?(二)——月:自旋锁 平行时空 在复制好上面那一行我就先停下来了,算是先占了个位置,虽然我知道大概要怎么写,不过感觉还是很乱. 我突然想到,既然那么纠结,那么混乱,那么不知所措,我们不如换个视角.记得高中时看过的为数不多的长篇小说<穆斯林的葬礼>,作者是:霍达(女),故事描写了两个发生在不同时代.有着不同的内容却又交错扭结的爱情悲剧,一个是“玉”的故事,一个是“月”

一个无锁消息队列引发的血案(六)——RingQueue(中) 休眠的艺术 [续]

目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的艺术 [续] 开篇 这是第五篇的后续,这部分的内容同时会更新和添加在 第五篇:RingQueue(中) 休眠的艺术 一文的末尾. 归纳 紧接上一篇的末尾,我们把 Windows 和 Linux 下的休眠策略归纳总结一下,如下图: 我们可以看到,Linux 下的 sched_yield() 虽然包括了

深入理解SPDK 之二: 消息和无锁队列

并发理论 期望: 随着硬件的线性增加,性能也线性增加: 传统 锁 的优点: 无锁 到有锁 扩展的方便: 锁直接加在共享数据的前面: 缺点:随着系统内线程的增加,数据和临界段的竞争越来越激烈,而且多个线程可能处于不同物理core,频繁竞争导致剧烈的L1 cache 失效. SPDK的做法:各管各妈:你看我娃 ** 各管各妈 SPDK takes a different approach altogether. Instead of placing shared data in a global l

谈谈存储软件的无锁设计

面向磁盘设计的存储软件不需要考虑竞争锁带来的性能影响.磁盘存储软件的性能瓶颈点在于磁盘,磁盘抖动会引入极大的性能损耗.因此,传统存储软件的设计不会特别在意处理器的使用效率.曾经对一个存储虚拟化软件进行性能调优,在锁竞争方面做了大量优化,最后也没有达到性能提升的效果,原因就在于存储虚拟化的性能瓶颈点在于磁盘,而不在于处理器的使用效率.正因为如此,在面向磁盘设计的软件中,很多都采用单线程.单队列处理的方式,一定程度上还可以避免由于并发所引入的磁盘抖动问题. 在面向NVMe SSD设计的存储软件中,这

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

[概述] 自从上次发布了[DIOCP开源项目-利用队列+0MQ+多进程逻辑处理,搭建稳定,高效,分布式的服务端]文章后,得到了很多朋友的支持和肯定.这加大了我的开发动力,经过几个晚上的熬夜,终于在昨天晚上,DEMO基本成型,今天再加入了QWorkers来做逻辑处理进程,进一步使得逻辑处理进程更加方便和高效.今天特意写篇blog来记录我的心得与大家分享. [功能实现说明] 沿用上次的草图 目前DEMO图上的功能都已经实现.下面谈谈各部分的实现. 通信服务, 由DIOCP实现,担当与客户端的通信工作

handy之日志--高性能无锁日志系统

服务器编程中,日志系统需要满足几个条件 .高效,日志系统不应占用太多资源 .简洁,为了一个简单的日志功能引入大量第三方代码未必值得 .线程安全,服务器中各个线程都能同时写出日志 .轮替,服务器不出故障是不重启的,半年一年的日志放到一个文件会导致文件过大 .及时保存,程序故障导致异常退出,此时需要通过日志诊断问题,不缓冲的日志系统更易用 著名的日志库有log4xxx系列,提供了非常灵活的功能,当然随之而来的代价就是庞大的库.在大多数服务器应用中,所需的功能不多,我偏向于选择一个支持按时间轮替的简洁

Nah Lock: 一个无锁的内存分配器

概述 我实现了两个完全无锁的内存分配器:_nalloc 和 nalloc.  我用benchmark工具对它们进行了一组综合性测试,并比较了它们的指标值. 与libc(glibc malloc)相比,第一个分配器测试结果很差,但是我从中学到了很多东西,然后我实现了第二个无锁分配器,随着核数增加至30,测试结果线性提高.核数增加至60,测试结果次线性提高,但是仅比tcmalloc好一点. 想要安装,输入命令: git clone ~apodolsk/repo/nalloc,阅读 README文档.

无锁环形队列

1 #include "stdafx.h" 2 #include <process.h> 3 #include <stdio.h> 4 #include <Windows.h> 5 #include <stdlib.h> 6 #include <assert.h> 7 8 #define MAX_VIDEO_BUFF 1024 9 10 struct Header 11 { 12 WORD wSize; 13 char dat