C++ 队列在没有推送的情况下弹出

c++ queue pop without push

本文关键字:情况下 队列 C++      更新时间:2023-10-16

我在 c++ 运行时应用程序上使用了很多std::queue<uint32_t> Queue。我需要了解,我可以推送到队列中的最大值数是多少,以及如果我使用任何 push_back(pop_front() 会发生什么。

有时,我的代码在尝试弹出值时会在线程内中断。

PostEvent(uint32_t EventUid)
{
    /* Create Event Thread only when 
       first event received (E_RESTART.COLD) */
    if (!isThreadCreated) {
        c_thread::start("event");
        isThreadCreated = true;
    }
    Queue.push_back(EventUid);
}

event_thread::运行():

while (isThreadAlive())
{
    while (Queue.size())
    {
        if (!Queue.empty())
        {
            uint32_t EventUid;
            EventUid = Queue[0];
            Queue.pop_front();
        }
    }
}

我还需要知道,我可以使用这样的数据结构吗

struct Counter_Elements
{
    uint32_t              eventId;
    std::string           applicationName;
    std::string           functionName;
    std::string           dataName; 
    std::string           dataValue;
    uint64_t              count;
    char                  tag;
};

并创建一个类似 std::queue<Counter_Elements> CountQueue 的队列。如果是这样,我可以推送的最大计数器元素数量是多少。

标准容器仅在只读情况下是线程安全的。例如,您需要在修改队列(推送和/或弹出)时使用互斥锁来保护队列。

通常,您需要从创建线程安全队列开始,如下所示:

template <class T, class Container = std::deque<T>> 
class ts_queue {
    Container c;
    std::mutex m;
public:
    void push(T const &v) { 
       std::lock_guard<std::mutex> l(m);
       c.push_back(v); 
    }
    bool pop(T &v) { 
       std::lock_guard<std::mutex> l(m);
       if (c.empty())
           return false;
       v = c.front();
       c.pop_front();
       return true;
    }
};

这样,在任何给定时间只有一个线程可以修改队列,从而保持队列安全。

请注意,我已经将pop的签名更改为我发现在进行多线程编程时(更)有用的签名。在典型情况下,您希望为弹出(也可能是推送)添加超时,因此如果在合理的时间内没有可用的数据,您只需放弃并返回 false。就目前而言,这是它的简化版本,如果数据不能立即可用,则返回 false。