bug*_*t77 14 c++ stack multithreading boost thread-safety
我是C++的新手,我正在编写一个多线程的应用程序,不同的编写者会将对象推入堆栈,读者将它们从堆栈中拉出(或者至少将指针推到对象上).
是否有内置于C++中的结构可以在不添加锁定代码等的情况下处理此问题?如果没有,Boost库怎么样?
编辑:
你好.感谢最初的好答案.我想我认为这可能是内置的一个原因是我纯粹在x86空间思考并且认为指针的PUSH/POP应该是指令级别的原子动作.
我不确定我最初的预感是否正确,但我想在所有平台上都不一定如此.虽然如果在x86上运行,你是否会将原子PUSH和POP发送到堆栈中,如果是这样,这实际上是否使它无锁?
Reu*_*nen 21
是的:Boost.Thread很棒,应该很好地满足你的需求.(现在,很多人都说你几乎可以将Boost视为内置功能.)
仍然没有可以开箱即用的类,但是一旦掌握了同步原语,例如,实现自己的线程安全包装就非常简单了std::stack.它可能看起来像这样(没有实现每个方法......):
template <typename T> class MyThreadSafeStack {
public:
void push(const T& item) {
boost::mutex::scoped_lock lock(m_mutex);
m_stack.push(item);
}
void pop() {
boost::mutex::scoped_lock lock(m_mutex);
m_stack.pop();
}
T top() const { // note that we shouldn't return a reference,
// because another thread might pop() this
// object in the meanwhile
boost::mutex::scoped_lock lock(m_mutex);
return m_stack.top();
}
private:
mutable boost::mutex m_mutex;
std::stack<T> m_stack;
}
Run Code Online (Sandbox Code Playgroud)
如果您不熟悉 C++,请了解RAII.与此案相关,Boost.Thread具有"范围锁定"类,因为忘记释放锁定而难以在腿部射击.
如果您发现自己编写的代码如下:
void doStuff() {
myLock.lock();
if (!condition) {
reportError();
myLock.unlock();
return;
}
try {
doStuffThatMayThrow();
}
catch (std::exception& e) {
myLock.unlock();
throw e;
}
doMoreStuff();
myLock.unlock();
}
Run Code Online (Sandbox Code Playgroud)
,那么你应该说不,然后去RAII(语法不直接来自Boost):
void doStuff() {
scoped_lock lock;
if (!condition) {
reportError();
return;
}
doStuffThatMayThrow();
doMoreStuff();
}
Run Code Online (Sandbox Code Playgroud)
关键是当scoped_lock对象超出范围时,它的析构函数会释放资源 - 在本例中是锁定.无论您是通过抛出异常退出范围,还是执行return您的同事偷偷在函数中间添加的奇怪语句,或者只是到达函数末尾,这都会发生.
小智 5
当前的 C++ 标准根本没有解决线程问题,因此您的第一个问题的答案是否定的。一般来说,将锁定构建到基本数据结构中是一个坏主意,因为它们没有足够的信息来正确和/或有效地执行它。相反,应该在使用数据结构的类中执行锁定 - 换句话说,在您自己的应用程序类中。