併發,非等分,環形緩衝區的一些疑問。。。

最近手裏的程序需要用到這麼個東西

乍一看,好像很簡單。但是實際操作起來感覺好複雜。

總結下來主要集中在以下幾個方面:

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;
                }
            }
        }

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章