您的位置:首页 > 其它

无锁(lock-free)队列的一个简单实现

2008-03-06 14:18 561 查看
作为 无锁的 ( lock-free ) 线程安全算法 的一个习作吧。思想、算法十分简单。

#ifdef WIN32
inline void sleep( uint32 mil )
{
Sleep( mil );
}
inline bool CAS(void* pDest, uint32 cmp, uint32 xchg){
return InterlockedCompareExchange(reinterpret_cast<PLONG>(pDest),
static_cast<LONG>(xchg), static_cast<LONG>(cmp)) == static_cast<LONG>(cmp);
}
inline int32 SafeInc(int32* pVal)
{
return static_cast<int32>(InterlockedIncrement(reinterpret_cast<PLONG>(pVal)));
}
inline int32 SafeDec(int32* pVal)
{
return static_cast<int32>(InterlockedDecrement(reinterpret_cast<PLONG>(pVal)));
}
#endif
//这儿告诉编译器按照8字节对齐
#ifdef _MSC_VER
#	pragma pack(push, 8)
#endif /* _MSC_VER */
template< typename T, int max_size=1024 >
class Quese
{
public:
Quese()
{
memset( _buf, 0, sizeof(T*) * max_size );
_begin=_end=0; _size=0;
}
void push( T* pVal )
{
if( pVal==0 ) return;
int32 cur;
bool loop=true;
do{
if ( _size == max_size  ) {
sleep( 1 ); // TODO: 扩展
continue;
}
cur=safe_move( &_end );;
loop=!CAS( _buf + cur , 0, (uint32)pVal );
}while( loop );
SafeInc( (int32*)&_size );
}
T * pop()
{
int32 cur;
T *p;
do{
if ( _size==0 ) return NULL;
cur=safe_move( &_begin );
p= _buf[cur];
}while( p==0 || !CAS( _buf + cur, (uint32)p, 0 ) );
SafeDec( (int32*)&_size );
return p;
}
public:
uint32 safe_move( volatile uint32* p )
{
uint32 next;
uint32 cmp;
do{
cmp=*p;
next=cmp+1;
if( next >= max_size ) next=0;
}while( !CAS( (uint32*)p, cmp, next ) );
return cmp;
}
T* _buf[max_size];
volatile uint32 _begin;
volatile uint32 _end;
volatile int32 _size;
};


这个队列的大小是固定的,很多情况下应该够用了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: