You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程操作中实现队列Push函数的阻塞等待(队列大小超5)

实现队列满时阻塞Push的多线程安全队列

你的需求是让自定义队列在大小超过5时,PushItem进入等待状态,直到队列有空闲空间(大小≤5)。下面是修改后的完整实现,同时修复了原代码中的几个线程安全问题:

template <typename T>
class CAMERA_DATA_QUEUE
{
private:
    std::queue<T> m_queue;
    std::mutex m_mutex;
    std::condition_variable m_cond;
    // 定义队列最大容量,方便后续修改
    const int MAX_SIZE = 5;

public:
    void PushItem(T item)
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        // 等待队列大小不超过最大容量
        m_cond.wait(lock, [this]() { return m_queue.size() <= MAX_SIZE; });
        
        m_queue.push(std::move(item)); // 用move减少拷贝,优化性能
        m_cond.notify_one(); // 通知可能等待的Pop线程
    }

    T Pop()
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        // 等待队列不为空
        m_cond.wait(lock, [this]() { return !m_queue.empty(); });
        
        T item = std::move(m_queue.front());
        m_queue.pop();
        m_cond.notify_one(); // 通知可能等待的Push线程(队列有空间了)
        return item;
    }

    void ResetQueue()
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        // 清空队列原内容
        std::queue<T> empty_queue;
        std::swap(m_queue, empty_queue);
        // 通知所有等待的线程(Push线程现在可以继续了)
        m_cond.notify_all();
    }

    int GetSize()
    {
        // 加锁保证线程安全,避免读取size时队列被其他线程修改
        std::lock_guard<std::mutex> lock(m_mutex);
        return m_queue.size();
    }
};

关键修改说明:

  1. PushItem的阻塞逻辑:

    • 使用std::condition_variable::wait等待队列大小不超过5,wait会自动释放锁并进入休眠,直到条件满足(队列size≤5)时重新获取锁,保证线程安全。
    • 用std::move传递item,避免不必要的拷贝,提升性能。
  2. Pop后的通知:

    • 弹出元素后,队列空闲空间增加,必须调用notify_one通知等待的Push线程,让它们检查是否可以继续入队。
  3. 修复ResetQueue:

    • 原代码中m_queue.empty()只是判断是否为空,并没有清空队列,这里用swap替换为空队列来清空内容。
    • 清空后调用notify_all,唤醒所有等待的Push和Pop线程,避免线程永久阻塞。
  4. 线程安全的GetSize:

    • 给GetSize加锁,因为m_queue.size()不是线程安全的操作,必须在锁保护下读取。

内容的提问来源于stack exchange,提问作者sumit kang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 02:14:58