zoukankan      html  css  js  c++  java
  • 并发,非等分,环形缓冲区的一些疑问。。。

    最近手里的程序需要用到这么个东西

    乍一看,好像很简单。但是实际操作起来感觉好复杂。

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

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

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

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

    这样一来问题似乎变得十分复杂化了。。。。十分非常复杂。而且每次分配内存的时候 都要考虑上面所有情况。。。真是很复杂。

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

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

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

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

    是网络层面的,由于发送速度不可能是恒定的,接受的数据量也无法准确预测,因此不可能确定缓冲区的准确大小。。。

    好吧,。。。⊙﹏⊙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;
                    }
                }
            }
    
  • 相关阅读:
    POJ 1795 DNA Laboratory
    CodeForces 303B Rectangle Puzzle II
    HDU 2197 本源串
    HDU 5965 扫雷
    POJ 3099 Go Go Gorelians
    CodeForces 762D Maximum path
    CodeForces 731C Socks
    HDU 1231 最大连续子序列
    HDU 5650 so easy
    大话接口隐私与安全 转载
  • 原文地址:https://www.cnblogs.com/SHGF/p/3464602.html
Copyright © 2011-2022 走看看