并发编程day 9

本文介绍了一种使用模板和锁机制实现的线程安全链表,提供了一系列方法如`push_front`、`remove_if`等,确保在多线程环境下数据操作的正确性和一致性。
摘要由CSDN通过智能技术生成

基于锁的线程安全的链表

//基于锁的线程安全的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 = &current;
            }
            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 = &current;
            }
            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();
}
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值