细粒度锁的极简单线程安全队列

template<typename T>
class ThreadsafeQueue
{
private:
    struct Node
    {
        std::shared_ptr<T>       data;
        std::unique_ptr<T>       next;
    };

    std::unique_ptr<Node>        head;
    Node*                        tail;
    mutable std::mutex           headMutex;
    mutable std::mutex           tailMutex;
    std::condition_variable      dataCond;

    Node* getTail () const
    {
        std::lock_guard<std::mutex> lock(tailMutex);
        return tail;
    }

    std::unique_lock<std::mutex> waitForData();

    std::unique_ptr<Node> popHead ()
    {
        std::lock_guard<std::mutex> lock(headMutex);
        auto oldHead = std::move(head);
        head = std::move(oldHead->next);
        return oldHead;
    }

    std::unique_ptr<Node> waitPopHead ()
    {
        std::unique_lock<std::mutex> lock(waitForData ());
        return popHead ();
    }

    std::unique_ptr<Node> waitPopHead (T& popedValue)
    {
        std::unique_lock<std::mutex> lock(waitForData ());
        popedValue = std::move(*head->data);
        return popHead ();
    }

    std::unique_ptr<Node> tryPopHead ()
    {
        std::lock_guard<std::mutex> lock(headMutex);
        if (head.get () == getTail ()){
            return std::unique_ptr<Node>();
        }
        return popHead ();
    }

    std::unique_ptr<Node> tryPopHead (T& popedValue)
    {
        std::lock_guard<std::mutex> lock(headMutex);
        if (head.get () == getTail ()){
            return std::unique_ptr<Node>();
        }
        popedValue = std::move(*head->data);
        return popHead ();
    }

public:
    ThreadsafeQueue():
        head(std::make_shared<T>()), tail(head.get ())
    {}

    ThreadsafeQueue(const ThreadsafeQueue&)            = delete;
    ThreadsafeQueue& operator=(const ThreadsafeQueue&) = delete;

    std::shared_ptr<T>           tryPop();
    bool                         tryPop(T&);
    std::shared_ptr<T>           waitAndPop();
    void                         waitAndPop(T& value);
    void                         push(T newValue);
    bool                         empty();
};

template<typename T>
void ThreadsafeQueue<T>::push (T newValue)
{
    auto const newData = std::make_shared<T>(std::move(newValue));
    auto       newNext = std::make_unique<Node>();
    auto       newTail = newNext.get();
    std::lock_guard<std::mutex> lock(tailMutex);
    tail->next = std::move(newNext);
    tail->data = newData;
    tail = newTail;
    dataCond.notify_one ();
}

template<typename T>
inline std::unique_lock<std::mutex> ThreadsafeQueue<T>::waitForData ()
{
    std::unique_lock<std::mutex> lock(headMutex);
    dataCond.wait(lock, [&]{return head != getTail ();});
    return std::move(lock);
}

template<typename T>
inline bool ThreadsafeQueue<T>::empty ()
{
    std::lock_guard<std::mutex> lock(headMutex);
    return (head.get () == getTail ());
}

template<typename T>
inline std::shared_ptr<T> ThreadsafeQueue<T>::waitAndPop ()
{
    auto const oldHead = waitPopHead ();
    return oldHead->data;
}

 template<typename T>
inline void ThreadsafeQueue<T>::waitAndPop (T& popedValue)
{
    waitPopHead (popedValue);
}

template<typename T>
inline std::shared_ptr<T> ThreadsafeQueue<T>::tryPop ()
{
    auto const oldHead = tryPopHead();
    return oldHead? oldHead->data : std::shared_ptr<T>();
}

template<typename T>
inline bool ThreadsafeQueue<T>::tryPop (T& popedValue)
{
    auto const oldHead = tryPopHead (popedValue);
    return oldHead;
}

 

 

转载于:https://www.cnblogs.com/wuOverflow/p/4840039.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux中的机制是用于多线程编程中保证数据同步的重要手段。粒度可以分为粗粒度粒度。 粗粒度是指在整个程序或进程中只有一把,这样当多个线程同时访问共享资源时,只能顺序地进行,从而导致性能瓶颈。而粒度则是指对共享资源进行分,使得不同的线程可以同时访问不同的资源,从而提高了程序的并发性能。 Linux内核中实现无化的方式主要有两种:基于原子操作的无化和基于RCU的无化。 基于原子操作的无化是通过使用原子操作来实现共享资源的同步,这样可以避免使用带来的性能开销。但是,由于原子操作只能保证单个变量的原子性,因此不能完全替代机制。 基于RCU的无化则是通过使用RCU(Read-Copy-Update)机制来实现共享资源的同步。在RCU机制下,读操作不需要进行加,而是通过对数据进行版本控制来避免读操作的竞争。而写操作则是通过先复制一份数据,然后对新数据进行修改,最后再替换旧数据来实现的。 在粒度的实现方面,Linux内核中提供了多种机制,例如读写、自旋、信号量等。不同的机制适用于不同的场景,需要根据实际情况进行选择。同时,对于特定的共享资源,也可以使用一些更高级的同步机制,例如无队列、无哈希表等,以进一步提高程序的并发性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值