多线程无锁(lock-free) 堆的实现

堆的多线程化处理比较简单,它只有一个指向堆顶的变量需要竞争,因此我们可以很方便的用 cas 操作来完成。

 

/* * Copyright (C) 2010 Chen Wang ( China ) * Email: [email protected] * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once #include "lockfree.hpp" #if !defined(_MSC_VER) || (_MSC_VER < 1600) # define nullptr NULL #endif namespace lichc { namespace lockfree { static_assert(sizeof(void *) == 4, "64-bit code generation is not supported."); template< typename T > class queue { public: queue() { _head.data=0; } void push( const T t ) { data* n=new data; n->value=t; int64 old,x; do{ old=_head.data; n->next=reinterpret_cast(old); // 高 32 位加一,这是为了处理 ABA 问题;低32位保存下一个对象的指针。 x=( old + 0x100000000LL ) & 0xFFFFFFFF00000000LL | reinterpret_cast(n); }while( !atomic_cas( &_head, old, x ) ); } bool pop( T& v ) { int64 old,x; data *olddata; do{ old=_head.data; if( (old & 0xFFFFFFFFLL) == 0 ) return false; olddata=reinterpret_cast( old ); x=( old + 0x100000000LL ) & 0xFFFFFFFF00000000LL | reinterpret_cast(olddata->next); }while( !atomic_cas( &_head, old, x ) ); v=olddata->value; delete olddata; return true; } private: struct data { data* next; // Next Node, nullptr for end. T value; }; private: atomic_int64 _head; }; }; }; 

 

代码来自我们正准备开源的 C++ 库,开发代号 lugce。

 

不明白什么是 lockfree 算法的可以参考我的这篇博文:http://blog.csdn.net/jadedrip/archive/2007/08/08/1731554.aspx

你可能感兴趣的:(C++)