并发,非等分,环形缓冲区的一些疑问。。。

最近手里的程序须要用到这么个东西网络

乍一看,好像很简单。可是实际操做起来感受好复杂。多线程

总结下来主要集中在如下几个方面:spa

1.分配(写入)的时候是顺序写入的,可是多线程情况下,每次写入完成时间是不肯定的。这样一来彷佛每一个块分配出去的缓冲区都要进行跟踪。而跟踪的难点也就在于,写入完成时间彻底是随机的。线程

那么当我程序 须要访问并读取这个缓冲区的数据时,如何判断哪些连续部分已经写完。。。?blog

要维护一个自动排序的列表,而且要二分查找。而且还要区分缓冲区会写(就是回到头上写入的状况),而且还要记录缓冲区尾部的位置(以供读取程序进行读取)。排序

这样一来问题彷佛变得十分复杂化了。。。。十分很是复杂。并且每次分配内存的时候 都要考虑上面全部状况。。。真是很复杂。内存

2.好的,还有一个严重的问题就是,当环形缓冲区溢出的时候 应该如何处理。这是一个让人很是头疼的问题。get

应该说判断是否 满,不难。可是要判断,如何处理问题来了。既然是缓冲区 固然是放数据喽。。。因此不可能放弃数据吧...?io

那么我惟一想到的解决方案就是再开辟一个临时内存空间,保存这块来不及处理的数据。可是,这彷佛又失去了环形缓冲的优点。。。ast

真尼玛太纠结了。。。因此,最好仍是要适当地分配比使用率大一些的缓冲区。。。?啥?不懂?我也不懂。好吧其实,个人应用的场合又比较特殊。

是网络层面的,因为发送速度不多是恒定的,接受的数据量也没法准确预测,所以不可能肯定缓冲区的准确大小。。。

好吧,。。。⊙﹏⊙b汗

我太纠结了。这个问题困扰了,好久好久了。。。。若是有大神看到的话,不妨指点指点。

 下面是一小段半吊子。。。。(智商捉急唉,写到一点点心力交瘁了,写不下去了)

    public class ShareBuffer
    {
        public ShareBuffer(int size)
        {
            buffer = new byte[size];
        }

        public byte[] buffer;



        public int CurOffSet;
        public int LastSendOffSet;
        //public SortedDictionary<int, ArraySegment<byte>> RecevieingOffList = new SortedDictionary<int, ArraySegment<byte>>();
        //public SortedDictionary<int, ArraySegment<byte>> ProRecevieingOffList = new SortedDictionary<int, ArraySegment<byte>>();
        //public SortedSet<int> RecevieingOffSets = new SortedSet<int>(); 

        public ArraySegment<byte> Take(int length)
        {
            int AddCur = CurOffSet;
            if (AddCur < buffer.Length)//若是已经被其余线程改得超出了Length,那么本线程就不参与了
            {
                AddCur = Interlocked.Add(ref CurOffSet, length);//拿到Offset+Count这块缓冲区的范围
                if (AddCur < buffer.Length)//再次判断范围是否超过缓冲区大小
                {
                    goto Do;
                    //
                }
            }
            Start:
            //若是超过,从缓冲区的开头处从头再来
            AddCur = Interlocked.CompareExchange(ref CurOffSet, 0, AddCur);//若是其余线程 没有更新这个值为0,那就当前线程来作这件事
            //AddCur = Interlocked.Exchange(ref CurOffSet, 0);
            AddCur = Interlocked.Add(ref CurOffSet, length);//直接分配内存,不须要关注CurOffSet的值

            if(AddCur > buffer.Length)
            {
                goto Start;
            }


            Do:
            //上面是分配内存
            int AddrOffsetStart = AddCur - length;

            //int first = RecevieingOffList.Keys.First();//获取当前使用中的最小的位置
            //int lastk = RecevieingOffList.Keys.Last();
            //if ((first < AddrOffsetStart && lastk > AddrOffsetStart)
            //    ||(
                
            //    ))
            //{ 

                
            //}
            ArraySegment<byte> partBuffer = new ArraySegment<byte>(buffer, AddrOffsetStart, length);
            //RecevieingOffList.Add(partBuffer.Offset, partBuffer);
            //var lastoff = lastk + RecevieingOffList[lastk].Count;

            return partBuffer;
            //return new ArraySegment<byte>(buffer, CurOffSet, length);
        }


        //Stack<ArraySegment<byte>> Pool = new Stack<ArraySegment<byte>>();


        public IList<ArraySegment<byte>> SendBuffer
        {
            get
            {
                if (CurOffSet > LastSendOffSet)//若是当前缓冲区位置大于最后发送的位置,那么直接返回 上一次最后发送到的位置到当前
                {
                    int curOffset = CurOffSet;
                    var list = new List<ArraySegment<byte>> { new ArraySegment<byte>(buffer, LastSendOffSet, curOffset) };
                    LastSendOffSet = curOffset;
                    return list ;
                }
                else if (CurOffSet < LastSendOffSet)
                {

                }
                else
                {
                    return null;
                }
            }
        }
相关文章
相关标签/搜索