11 Haziran 2017 Pazar

lockfree queue Sınıfı

Giriş
Şu satırı dahil ederiz.
#include <boost/lockfree/queue.hpp>
T için kurallar şöyle
T must have a copy constructor
T must have a trivial assignment operator
T must have a trivial destructor
boost::function<void> bu koşulları sağlamadığı için kuyruk tipi olamaz
constructor - fixed size
Şöyle yaparız.
boost::lockfree::queue<int*> q (100);
Şöyle yaparız.
typedef boost::lockfree::queue<MyMessage, boost::lockfree::fixed_sized<true>> q
Daha sonra kuyruğun büyüklüğünü tanımlarız. Büyüklük 65535'i geçemez, yoksa exception atar.
typedef boost::lockfree::queue<int, boost::lockfree::fixed_size<true>> MyQueue;
MyQueue queue (1024*100);
Şu kod derlenmez.
typedef struct stack { 
  boost::lockfree::queue<int> queue (128);
} stack;
Şöyle yaparız.
struct stack { 
  boost::lockfree::queue<int> queue1;

  // initialize the member objects
  stack() : queue1 (128) {}
}
consume_all metodu
Şöyle yaparız.
lockfree::queue<uint64_t> q = ...;
q.consume_all (myfunctor); 
is_lock_free metodu
Açıklaması şöyle
Not all hardware supports the same set of atomic instructions. If it is not available in hardware, it can be emulated in software using guards. However this has the obvious drawback of losing the lock-free property.
İmzası şöyle
bool is_lock_free (void) const;
push metodu
Şöyle yaparız.
uint64_t m = ...;
q.push (m);
Diğer
deallocate_impl
Açıklaması şöyle
... the boost::lockfree::detail::freelist class is used to manage storage for a lock-free data structure (e.g., a queue), using a free list. The deallocate_impl method is used to free nodes by linking them back into the free list (a freed node becomes the new head of the free list, displacing the old head). This method is supposed to be thread-safe and lock-free.
Kodu şöyle
void deallocate_impl (index_t index)
{
  freelist_node * new_pool_node =
    reinterpret_cast<freelist_node*>(NodeStorage::nodes() + index);

  tagged_index old_pool = pool_.load(memory_order_consume);

  for(;;) {
   
    tagged_index new_pool (index, old_pool.get_tag());
    new_pool_node->next.set_index(old_pool.get_index());

    if (pool_.compare_exchange_weak(old_pool, new_pool))
      return;
  }
}

Hiç yorum yok:

Yorum Gönder