基于锁的线程安全的链表
//基于锁的线程安全的list
template<typename T>
class thread_safe_list{
private:
struct node
{
std::mutex _m;
std::shared_ptr<T> _data;
std::unique_ptr<node> next;
node(){}
node(const T& value):_data(std::make_shared<T>(value)){}
};
node head;
std::mutex last_ptr_mtx;
node last_node_ptr;
public:
thread_safe_list(){}
~thread_safe_list(){
remov_if([](const node&){return true;});
}
thread_safe_list(const thread_safe_list&)=delete;
thread_safe_list&operator=(const thread_safe_list&)=delete;
template<typename Predicate>
void remove_if(Predicate p)
{
node* current = &head;
std::unique_lock<std::mutex> lk(head.m);
while (node* const next = current->next.get())
{
std::unique_lock<std::mutex> next_lk(next->m);
if (p(*next->data))
{
std::unique_ptr<node> old_next = std::move(current->next);
current->next = std::move(next->next);
//判断删除的是否为最后一个节点
if (current->next == nullptr) {
std::lock_guard<std::mutex> last_lk(last_ptr_mtx);
last_node_ptr = ¤t;
}
next_lk.unlock();
}
else
{
lk.unlock();
current = next;
lk = std::move(next_lk);
}
}
}
template<typename Predicate>
bool remove_first(Predicate p)
{
node* current = &head;
std::unique_lock<std::mutex> lk(head.m);
while (node* const next = current->next.get())
{
std::unique_lock<std::mutex> next_lk(next->m);
if (p(*next->data))
{
std::unique_ptr<node> old_next = std::move(current->next);
current->next = std::move(next->next);
//判断删除的是否为最后一个节点
if (current->next == nullptr) {
std::lock_guard<std::mutex> last_lk(last_ptr_mtx);
last_node_ptr = ¤t;
}
next_lk.unlock();
return true;
}
lk.unlock();
current = next;
lk = std::move(next_lk);
}
return false;
}
void push_front(T const& value){
std::unique_ptr<node> new_node(new node(value));
std::lock_guard<std::mutex> lk(head.m);
new_node->next = std::move(head.next);
head.next = std::move(new_node);
//更新最后一个节点
if (head.next->next == nullptr) {
std::lock_guard<std::mutex> last_lk(last_ptr_mtx);
last_node_ptr = head.next.get();
}
}
template<typename Predicate>
std::shared_ptr<T> find_first_if(Predicate p){
node* current = &head;
std::unique_lock<std::mutex> lk(head.m);
while (node* const next = current->next.get())
{
std::unique_lock<std::mutex> next_lk(next->m);
lk.unlock();
if (p(*next->data))
{
return next->data;
}
current = next;
lk = std::move(next_lk);
}
return std::shared_ptr<T>();
}
template<typename Function>
void for_each(Function f){
node* current = &head;
std::unique_lock<std::mutex> lk(head.m);
while (const node* next = current->next.get())
{
std::unique_lock<std::mutex> next_lk(next->m);
lk.unlock();
f(*next->data);
current = next;
lk = std::move(next_lk);
}
}
void push_back(T const& value) {
//防止于push_head同时进行
//并且保证头部或者删除节点更新last_node_ptr唯一, 所以同时加锁
std::unique_ptr<node> new_node(new node(value));
std::lock(last_node_ptr->_m, last_ptr_mtx);
std::unique_lock<std::mutex> lk(last_node_ptr->_m, std::adopt_lock);
std::unique_lock<std::mutex> last_lk(last_ptr_mtx, std::adopt_lock);
//原来的最后节点的下一个节点指向新生成的节点
last_node_ptr->next = std::move(new_node);
//将最后一个节点后移
last_node_ptr = last_node_ptr->next.get();
}
};