我在c ++运行时应用程序上使用了很多std::queue<uint32_t> Queue
。
我需要了解,我可以推送到队列中的最大值是多少,如果我 pop_front()与任何 push_back()会发生什么。
有时我的代码在尝试弹出值时会在线程内部中断。
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
的队列。如果是这样,我可以推动的最大计数器元素数量。
答案 0 :(得分:0)
标准容器仅对于只读情况是线程安全的。您需要使用(例如)互斥锁来在修改队列时保护队列(推送和/或弹出)。
通常,您希望从创建线程安全队列开始,如下所示:
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
的签名更改为我发现的(更多)更有用的签名。在典型情况下,您希望为pop添加超时(也可能是推送),因此如果在合理的时间内没有可用的数据,您只需放弃并返回false。就目前而言,这是一个简化版本,如果数据不能立即返回,则返回false。