@Cupper

Вызов current_exception параллельно для одного объекта исключения

Хотел бы обратится к сообществу для прояснения не совсем ясной мне ситуации.

Речь идет о exception_ptr, rethrow_exception и current_exception в boost. Суть проблемы следующая: должно ли быть потокебезопасно выполнение current_exception (в нескольких потоках) после rethrow_exception для общего объекта исключения.


#include <iostream>
#include <exception>
#include <stdexcept>
#include <vector>

//#define USE_CPP11

#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <thread>
#include <future>
#include <memory>
#else
#include <boost>
#include <boost>
using namespace boost;
#endif

using namespace std;

void executer(mutex& mtx, exception_ptr ex)
{
	for(int i = 0; i < 9999999; i++)
	{
		try
		{
			lock_guard<mutex> lck(mtx);
			rethrow_exception(ex);
		}
		catch(...)
		{
			current_exception(); // <- run concurrently
		}
	}
}
void test()
{
	exception_ptr ex;

	try
	{
		throw runtime_error("O_o");
	}
	catch(...)
	{
		// use current_exception() it's compulsory condition
		// because only in this case will be used unsafe detail::refcount_ptr
		// (in current_exception_std_exception_wrapper inherited from exception)
		ex = current_exception();
	}

	mutex mtx;
	vector<shared_ptr> > group;
	for(int i = 0; i < 10; i++)
		group.push_back(shared_ptr<thread>(new thread(bind(executer, ref(mtx), ex))));
	
	vector<shared_ptr> >::iterator it = group.begin();
	for(; it != group.end(); it++)
	    (*it)->join();
}

void version()
{
#ifdef __GXX_EXPERIMENTAL_CXX0X__
    cout << "use c++11 implementation\n";
#else
    cout << "use boost implementation\n";
#endif
}

int main()
{
    version();
	cout << "Start\n";

	test();

	cout << "Exit\n";
}
</shared_ptr></thread></shared_ptr></mutex></boost></boost></memory></future></thread></vector></stdexcept></exception></iostream>

данный пример падает если использовать boost и не падает если использовать std реализацию (-std=c++11).

Стандарт по этому поводу пишет следующее

18.8.5 Exception propagation ... For purposes of determining the presence of a data race, operations onexception_ptr objects shall access and modify only the exception_ptrobjects themselves and not the exceptions they refer to. Use of rethrow_exceptionon exception_ptr objects that refer to the same exception object shallnot introduce a data race. [Note: if rethrow_exception rethrows the same exception object (ratherthan a copy), concurrent access to that rethrown exception object may introduce a data race. Changesin the number ofexception_ptrobjects that refer to a particular exception do not introduce a datarace.—end note]

То что описано в note это как раз моя ситуация, только я не понимаю, так должно быть или так не должно быть?

  • Вопрос задан
  • 2892 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы