博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个比较特别的池设计
阅读量:6365 次
发布时间:2019-06-23

本文共 2753 字,大约阅读时间需要 9 分钟。

最近打算用Redis用在产品中,所以相应会用到Redis .net client.由于自身也是写网络应用方面的所以自然就想了解一下代码看写得怎样.在打开代码的时候第一眼发现比较熟悉的一个对象BufferPool.打开一看发现设计比较特别,在整个Pool的获取和回收上没有用于我们常用的锁对象,也没有用于.NET带的轻量级的自旋锁.而是通过.net提供的原子锁来实现一个简单的自旋锁.

///     /// Courtesy of @marcgravell    /// http://code.google.com/p/protobuf-net/source/browse/trunk/protobuf-net/BufferPool.cs    ///     internal class BufferPool    {        internal static void Flush()        {            for (int i = 0; i < pool.Length; i++)            {                Interlocked.Exchange(ref pool[i], null); // and drop the old value on the floor            }            System.Collections.Generic.st        }        private BufferPool() { }        const int PoolSize = 1000; //1.45MB        internal const int BufferLength = 1450; //MTU size - some headers        private static readonly object[] pool = new object[PoolSize];        internal static byte[] GetBuffer()        {            object tmp;            for (int i = 0; i < pool.Length; i++)            {                if ((tmp = Interlocked.Exchange(ref pool[i], null)) != null)                     return (byte[])tmp;            }            return new byte[BufferLength];        }        internal static void ResizeAndFlushLeft(ref byte[] buffer, int toFitAtLeastBytes, int copyFromIndex, int copyBytes)        {            Debug.Assert(buffer != null);            Debug.Assert(toFitAtLeastBytes > buffer.Length);            Debug.Assert(copyFromIndex >= 0);            Debug.Assert(copyBytes >= 0);            // try doubling, else match            int newLength = buffer.Length * 2;            if (newLength < toFitAtLeastBytes) newLength = toFitAtLeastBytes;            var newBuffer = new byte[newLength];            if (copyBytes > 0)            {                Buffer.BlockCopy(buffer, copyFromIndex, newBuffer, 0, copyBytes);            }            if (buffer.Length == BufferLength)            {                ReleaseBufferToPool(ref buffer);            }            buffer = newBuffer;        }                internal static void ReleaseBufferToPool(ref byte[] buffer)        {            if (buffer == null) return;            if (buffer.Length == BufferLength)            {                for (int i = 0; i < pool.Length; i++)                {                    if (Interlocked.CompareExchange(ref pool[i], buffer, null) == null)                    {                        break; // found a null; swapped it in                    }                }            }            // if no space, just drop it on the floor            buffer = null;        }    }

刚开始看这代码感觉真的很怪,想为什么不用stack..如果池经常为空的时候这样操作是很损耗效能.不过经过详细思考后发现其实这种设计如果当buffer占用到回收之间的时间很短那整个设计来看似乎很不错,池出现为空的情况很少基本只会自旋锁几下就可以了,这样做解决一些锁对象的开销;在密集处理情况效果应该不错,以上紧紧是过去设计经验判断的是不是真的还真要具体测验证.

有经验的朋友不知道对这样的设计有什么看法?

转载地址:http://rkoma.baihongyu.com/

你可能感兴趣的文章
物联网影响商业发展三要素
查看>>
China Unicom and Chunghwa Telecom work together&nb
查看>>
Java图片上查找图片算法
查看>>
Python fabric实现远程操作和部署
查看>>
详解Java中staitc关键字
查看>>
前中情局局长:FBI目的是从根本上改善iPhone
查看>>
大隐隐于市,你身边的那些安全隐患你都知道么?
查看>>
物联网市场迅猛发展 “中国芯”如何把握机会?
查看>>
aws 上使用elb 的多域名问题
查看>>
环球花木网的目标就是致力于打造成为“园林相关行业的专业性门户网站
查看>>
《编写高质量代码:改善c程序代码的125个建议》—— 建议14-1:尽量避免对未知的有符号数执行位操作...
查看>>
《C语言编程魔法书:基于C11标准》——2.2 整数在计算机中的表示
查看>>
全球程序员编程水平排行榜TOP50,中国排名第一
查看>>
HDFS 进化,Hadoop 即将拥抱对象存储?
查看>>
Edge 浏览器奇葩 bug:“123456”打印成“114447”
查看>>
Sirius —— 开源版的 Siri ,由 Google 支持
查看>>
《OpenGL ES应用开发实践指南:Android卷》—— 2.7 小结
查看>>
《Windows Server 2012活动目录管理实践》——第 2 章 部署第一台域控制器2.1 案例任务...
查看>>
Java Date Time 教程-时间测量
查看>>
Selector.wakeup实现注记
查看>>