复制提升::跨线程崩溃的异常
copying boost::exception across threads crashing
下面的示例代码将 boost::exception 对象从 1 个线程复制到另一个线程,由于破坏异常/exception_ptr内部状态期间的竞争条件而崩溃。我不确定解决它的最佳方法是什么。
使用的增强版本是1.42,平台是运行在双核Intel m/c上的Ubuntu lucid。编译器是 gcc 4.4.3。
#include <iostream>
#include <boost/exception/all.hpp>
#include <boost/thread.hpp>
struct Exception
: public virtual std::exception
, public virtual boost::exception
{
};
struct MyException : public virtual Exception {};
struct MyTag {};
typedef boost::error_info<MyTag, std::string> MyError;
struct Test
{
Test()
{
_t.reset(new boost::thread(boost::bind(&Test::executor, this)));
}
~Test()
{
_t->join();
}
void executor()
{
std::cerr << "executor: starting ...n";
for (;;)
{
boost::unique_lock<boost::mutex> lk(_mx);
while(_q.empty())
{
_cv.wait(lk);
}
{
boost::shared_ptr<boost::promise<int> > pt = _q.front();
_q.pop_front();
lk.unlock();
pt->set_exception(boost::copy_exception(MyException() << MyError("test")));
}
}
}
void run_impl()
{
try
{
boost::shared_ptr< boost::promise<int> > pm(new boost::promise<int>());
boost::unique_future<int> fu = pm->get_future();
{
boost::unique_lock<boost::mutex> lk(_mx);
_q.push_back(pm);
pm.reset();
}
_cv.notify_one();
fu.get();
assert(false);
}
catch (const MyException& e)
{
throw;
}
catch (const boost::exception& )
{
assert(false);
}
catch (...)
{
assert(false);
}
}
void run()
{
std::cerr << "run: starting ...n";
for (;;)
{
try
{
run_impl();
}
catch (...)
{
}
}
}
private:
boost::mutex _mx;
std::list< boost::shared_ptr< boost::promise<int> > > _q;
boost::shared_ptr<boost::thread> _t;
boost::condition_variable_any _cv;
};
int main()
{
Test test;
test.run();
}
/*
#0 0x080526bd in boost::exception_detail::refcount_ptr<boost::exception_detail::error_info_container>::release (this=0x806e26c) at /boost_1_42_0/boost/exception/exception.hpp:79
#1 0x0804f7c5 in ~refcount_ptr (this=0x806e26c, __in_chrg=<value optimized out>) at /boost_1_42_0/boost/exception/exception.hpp:34
#2 0x0804bb61 in ~exception (this=0x806e268, __in_chrg=<value optimized out>) at /boost_1_42_0/boost/exception/exception.hpp:254
#3 0x0805579a in ~clone_impl (this=0x806e260, __in_chrg=<value optimized out>, __vtt_parm=<value optimized out>) at /boost_1_42_0/boost/exception/exception.hpp:391
#4 0x001ff633 in ?? () from /usr/lib/libstdc++.so.6
#5 0x0027233d in _Unwind_DeleteException () from /lib/libgcc_s.so.1
#6 0x001fe110 in __cxa_end_catch () from /usr/lib/libstdc++.so.6
#7 0x0804f7a4 in Test::run (this=0xbffff74c) at ex_org.cpp:89
#8 0x0804b869 in main () at ex_org.cpp:106
*/
我不是提升专家,但我注意到一些比赛问题,它在调试模式下运行正常吗?
对于执行人,我会这样写
void executor()
{
std::cerr << "executor: starting ...n";
for (;;)
{
_cv.wait(lk);
boost::unique_lock<boost::mutex> lk(_mx);
__sync_synchronize (); // Tells the compiler to prevent optimizations
if ( !_q.empty() ) {
boost::shared_ptr<boost::promise<int> > pt = _q.front();
_q.pop_front();
pt->set_exception(boost::copy_exception(MyException() << MyError("test")));
}
}
}
以及
void run_impl()
{
try
{
boost::shared_ptr< boost::promise<int> > pm(new boost::promise<int>());
boost::unique_future<int> fu = pm->get_future();
{
boost::unique_lock<boost::mutex> lk(_mx);
// prevent the compiler from mixing above and below code
__sync_synchronize ();
_q.push_back(pm);
pm.reset();
}
_cv.notify_one();
// This one is the paranoïd's one ;), one must check without !
__sync_synchronize ();
{
// since fu must holds an internal reference pm being currently
// changed by the other thread !
boost::unique_lock<boost::mutex> lk(_mx);
// Then you are assured that everything is coherent at this point
// the stack frame holding the exception stuffs won't be corrupted
fu.get();
}
assert(false);
}
相关文章:
- Android NDK - C++ 异常会导致第三方原生库崩溃
- SDL_Image库会使程序崩溃或使其行为异常
- Clang 崩溃,在 std::async 中出现字符 * 异常
- 引发导致调用析构函数的异常会使程序崩溃
- C ++程序中的异常行为,经常崩溃
- 为什么 ArrayIndexOutOfBound 异常可以在 Java 中捕获,但C++程序反而崩溃
- 为什么我的代码崩溃了,浮点异常
- 程序崩溃,说向量不超出范围异常
- 助推.测试崩溃,***异常:MSVC上的其他
- 程序在函数声明时崩溃,出现未经处理的异常:堆栈溢出
- 由于删除(试图处理异常..)而崩溃
- 如何调试C++非托管代码中的较低级别文件访问异常/崩溃
- VC++异常处理-应用程序无论如何都会崩溃
- 队列用户APC - 抛出异常崩溃,可能是 mingw 错误
- 复制提升::跨线程崩溃的异常
- C++:我应该捕获所有异常还是让程序崩溃
- 为什么我的程序从异常中崩溃,即使我捕获了异常类型
- 防止c++异常导致Perl脚本崩溃
- 程序崩溃并显示消息"terminate called recursively"而不引发任何异常
- 在Windows上支持线程的Qt应用程序中的c++崩溃/异常处理程序