2013-05-31 22 views
1

的如下描述:升壓原子:無等待環形緩衝區大量我想用<code>boost::atomic</code>一個免費的等待環緩衝器的數據

Boost Example

producer在提供大量數據同一時間(無符號字符,+ - 3000值),就像一個矩陣它將逐行填充。 push緩衝區中這些值的最佳方式是什麼?我應該繞過它們嗎?或者我可以以某種方式在裏面memcpy

也是一樣pop如果我想在同一時間閱讀一堆值的...


這裏是我想出了,任何理由這不應該被好? 我只需要確保RINGBUFFERSIZE % iSize = 0

#define RINGBUFFERSIZE = 30000 

ring_[RINGBUFFERSIZE]; 

bool push(unsigned char* iData, int iSize) 
{ 
    size_t head = head_.load(boost::memory_order_relaxed); 
    size_t next_head = next(head,iSize); 
    if (next_head == tail_.load(boost::memory_order_acquire)) 
    return false; 
    memcpy(ring_+head,iData,iSize); 
    head_.store(next_head, boost::memory_order_release); 
} 

bool pop(unsigned char * value, int iSize) 
{ 
    size_t tail = tail_.load(boost::memory_order_relaxed); 
    if (tail == head_.load(boost::memory_order_acquire)) 
     return false; 
    value = &ring_[tail]; 
    tail_.store(next(tail,iSize), boost::memory_order_release); 
    return true; 
} 


size_t next(size_t current, int iSize) 
{ 
    return (current + iSize) % RINGBUFFERSIZE; 
} 
+0

建議的解決方案不太合適,因爲'next_head'可能已經包裝了。在這種情況下,你沒有連續的塊,不能做一個'memcpy'(當然,你可以檢查這個案例,也可以做兩個)。 – Useless

回答

1

最快的方法是推動一個指針(unsigned char *或指向某個包含長度的結構的指針)。

當然,假設可以強制pop採用與推送完全相同的塊,這只是解決了問題:現在您必須以某種方式管理這些緩衝區的分配。用於管理數據塊


簡單的樣品溶液:

  1. 預分配「足夠」固定大小塊的對象(比如動態長度+ unsigned char data[3096]或其他)
  2. 塊的發送地址在您的等待免費環形緩衝區
  3. 發送地址返回當消費者完成它時,所以生產者可以回收相同的塊對象

如果你真的不能做到這一點,你可以爲您塊和大小的值的推/彈出對象的最大尺寸......不過說實話,這似乎很浪費的(即使對象知道它的長度,所以不需要對整個3k數組進行更小塊的memcpy)。

+0

確切地說,指向的內存不再有效,所以我需要複製數據本身。 – Smash

+0

你當然可以控制緩衝區的有效性嗎? – Useless

+0

數據來自tcp連接,所以我需要每讀一次就存儲一次。 – Smash