Pol*_*878 7 c++ concurrency multithreading thread-safety
我想知道这是否是在C++中编写线程安全队列的正确方法?
template <class T>
class Queue
{
public:
Queue() {}
void Push(T& a)
{
m_mutex.lock();
m_q.push_back(a);
m_mutex.unlock();
}
T& Pop()
{
m_mutex.lock();
T& temp = m_q.pop();
m_mutex.unlock();
return temp;
}
private:
std::queue<t> m_q;
boost::mutex m_mutex;
};
Run Code Online (Sandbox Code Playgroud)
你明白了......我只是想知道这是不是最好的方法.谢谢!
编辑: 由于我得到的问题,我想澄清互斥量是一个boost :: mutex
Eli*_*ght 19
我建议使用Boost线程库来帮助您.
你的代码很好,除了你用C++编写代码时
some_mutex.lock();
// do something
some_mutex.unlock();
Run Code Online (Sandbox Code Playgroud)
然后,如果该// do something部分中的代码抛出异常,则永远不会释放锁.Boost库使用诸如lock_guard之类的类来解决这个问题,在该类中初始化一个在其构造函数中获取锁的对象,以及析构函数释放锁的对象.这样你就知道你的锁将永远被释放.其他语言通过try/finally语句实现此目的,但C++不支持此构造.
特别是,当您尝试从没有元素的队列中读取时会发生什么?这会引发异常吗?如果是这样,那么你的代码会遇到问题.
当试图获得第一个元素时,你可能想要检查是否存在某些东西,然后如果不存在就去睡觉并等到某个东西.这是一个条件对象的工作,也是由Boost库提供的,如果您愿意,可以在较低级别提供.
从线程角度来看,这看起来适合于简单的线程安全队列.
但是你有一个问题:std :: queue的pop()不会返回从队列中弹出的元素.你需要做的是:
T Pop()
{
m_mutex.lock();
T temp = m_q.front();
m_q.pop();
m_mutex.unlock();
return temp;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您不希望返回引用,因为引用的元素正从队列中弹出并被销毁.
你还需要有一些公共的Size()函数来告诉你队列中有多少元素(或者你需要优雅地处理调用Pop()并且队列中没有元素的情况) .
编辑: 虽然,正如Eli Courtwright指出的那样,你必须小心抛出异常的队列操作,并且使用Boost是一个好主意.