4
다음은 예외/exception_ptr 내부 상태가 파괴되는 동안 경쟁 조건으로 인해 1 스레드에서 다른 스레드로 boost :: exception 오브젝트를 복사/전송하는 샘플 코드입니다. 나는 그것을 해결하는 가장 좋은 방법은 무엇인지 모르겠습니다.부스트간에 복사 boost :: exception이 발생했습니다.
사용 된 부스트 버전은 1.42이고 플랫폼은 듀얼 코어 Intel m/c에서 실행되는 우분투입니다. 컴파일러는 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
*/
등이
처럼 쓴다 무엇 참조보다는 비 참조를 잡기는 어떻습니까? 그래서 로컬 사본이 생성됩니다. – Nick
도움이되지 않지만 여전히 동일한 충돌로 끝납니다. – Harish
g ++ 4.7.0을 사용하여 이것을 재현하려고 시도했지만 1.49가 향상되었지만 예제가 Intel i5의 아치 리눅스 3.4.0에서 완벽하게 작동합니다. – nijansen