三.
void push_back(int data)
{
end->data = data;
if(end->next == beg){
end->next = new ListNode(0,end->next);
}
end = end->next;
}
在这个处理过程中,beg指针可能被读线程移动到下一位,但对这里实现的逻辑没有任何影响,而且最终逻辑也是正确的。
void pop_front()
{
if(beg != end) beg = beg->next;
}
同样在这个处理过程中,end指针可能被写线程移动到下一位,但对这里实现的逻辑没有任何影响,而且最终逻辑也是正确的。
其他接口的实现都是没有什么变化:
int front()
{
return beg->data;
}
boolean empty()
{
return beg == end;
}
int size()
{
int size = 0;
ListNode* ptmp = beg;
ListNode* pend = end;
for(ListNode* ptmp = beg; ptmp != pend; ptmp = ptmp->next, size);
return size;
}
注意函数实现过程中用了临时变量来保存当时的end指针,为了防止在size执行过程中,另一个线程不停的插入数据,导致这个循环无法终止,这样得到的值可以看作是列表某个时间的一个快照数据,和列表在size函数执行完毕后的真实大小可能有差异,这是多线程的特性所决定的,可以认为在这种处理方式下,出现这种误差是可以接受的。
http://www.mscto.com
可以为WriteList,ReadList加上size接口。多个线程都使用WriteList(或ReadList)那么是需要加锁进行线程同步的,但WriteList和ReadList的接口可以分别在多个线程中使用是不需要加锁进行线程同步的。
下面是实作代码,供参考。
/*******************************************
author: htj
********************************************/
#ifndef CIRCLE_LIST_H
#define CIRCLE_LIST_H
#include
template >
class CircleList
{
struct ListNode;
typedef ListNode* node_pointer;
typedef ListNode node_type;
public:
typedef Alloc allocator_type;
typedef T value_type;
typedef typename allocator_type::size_type size_type;
typedef typename allocator_type::difference_type difference_type;
typedef typename allocator_type::reference reference;
typedef typename allocator_type::const_reference const_reference;
http://www.mscto.com
typedef typename allocator_type::pointer pointer;
typedef typename allocator_type::const_pointer const_pointer;
CircleList():m_end(allocate()),m_beg(m_end),m_size(0)
{
}
~CircleList()
{
for(node_pointer pbeg = m_beg; pbeg != m_end; pbeg->freeValue(), pbeg = pbeg->next);
node_pointer end = m_end;
node_pointer beg;
do{
beg = m_end->next;
deallocate(m_end);
m_end = beg;
}while(m_end != end);
}
void push_back(const_reference v)
{
void push_back(int data)
{
end->data = data;
if(end->next == beg){
end->next = new ListNode(0,end->next);
}
end = end->next;
}
在这个处理过程中,beg指针可能被读线程移动到下一位,但对这里实现的逻辑没有任何影响,而且最终逻辑也是正确的。
void pop_front()
{
if(beg != end) beg = beg->next;
}
同样在这个处理过程中,end指针可能被写线程移动到下一位,但对这里实现的逻辑没有任何影响,而且最终逻辑也是正确的。
其他接口的实现都是没有什么变化:
int front()
{
return beg->data;
}
boolean empty()
{
return beg == end;
}
int size()
{
int size = 0;
ListNode* ptmp = beg;
ListNode* pend = end;
for(ListNode* ptmp = beg; ptmp != pend; ptmp = ptmp->next, size);
return size;
}
注意函数实现过程中用了临时变量来保存当时的end指针,为了防止在size执行过程中,另一个线程不停的插入数据,导致这个循环无法终止,这样得到的值可以看作是列表某个时间的一个快照数据,和列表在size函数执行完毕后的真实大小可能有差异,这是多线程的特性所决定的,可以认为在这种处理方式下,出现这种误差是可以接受的。
http://www.mscto.com
可以为WriteList,ReadList加上size接口。多个线程都使用WriteList(或ReadList)那么是需要加锁进行线程同步的,但WriteList和ReadList的接口可以分别在多个线程中使用是不需要加锁进行线程同步的。
下面是实作代码,供参考。
/*******************************************
author: htj
********************************************/
#ifndef CIRCLE_LIST_H
#define CIRCLE_LIST_H
#include
template >
class CircleList
{
struct ListNode;
typedef ListNode* node_pointer;
typedef ListNode node_type;
public:
typedef Alloc allocator_type;
typedef T value_type;
typedef typename allocator_type::size_type size_type;
typedef typename allocator_type::difference_type difference_type;
typedef typename allocator_type::reference reference;
typedef typename allocator_type::const_reference const_reference;
http://www.mscto.com
typedef typename allocator_type::pointer pointer;
typedef typename allocator_type::const_pointer const_pointer;
CircleList():m_end(allocate()),m_beg(m_end),m_size(0)
{
}
~CircleList()
{
for(node_pointer pbeg = m_beg; pbeg != m_end; pbeg->freeValue(), pbeg = pbeg->next);
node_pointer end = m_end;
node_pointer beg;
do{
beg = m_end->next;
deallocate(m_end);
m_end = beg;
}while(m_end != end);
}
void push_back(const_reference v)
{