Я и моя команда разрабатываем библиотеку классов, которая выполняет обработку данных.
Эта обработка — многопоточная.
OS — Windows 7 / 64 + SP1.
Заказчик настаивает, на варианте, когда в случае ошибки ему будут поступать exception-s.
Мне, конечно же, несложно выполнить throw, однако при этом во "внешнем" (головном) потоке исключения на будет.
Пока мы планируем ввести глобальный флаг (скорее даже Event), который устанавливаем при ошибке.
Естественно, этот глобальный (либо статический) объект мы защитим критической секцией.
Далее, код, выполняемый в головном потоке "на нашей стороне" будет сканировать этот Event (с прокачкой windows-messages) и там уже,
если имела место проблема, выполнять throw...
В то же время, я чувствую, что есть более удачные варианты (без глобальных или статических переменных)...
ПРИМЕЧАНИЕ:
Мы все пишем на MSVC-2015, однако Заказчик настаивает только на применении стандарта C++03
В то же время, мы широко используем boost и STL.
С этими библиотеками Заказчик хорошо знаком.
Заранее благодарю, за любые соображения по данному вопросу!
Ну в таких ситуациях обычная практика наверное перехватывать в рабочем потоке все исключения, складывая их в std::exception_ptr, а потом кидать в основном потоке, когда тот полезет проверять состояние (запрашивать результат) у этого рабочего потока.
>настаивает только на применении стандарта C++03
А чем это аргументируется?
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re: Передать ошибку "наверх" из многопоточнй библиотеки
Здравствуйте, AlexGin, Вы писали:
AG>Я и моя команда разрабатываем библиотеку классов, которая выполняет обработку данных. AG>Эта обработка — многопоточная. AG>OS — Windows 7 / 64 + SP1. AG>Заказчик настаивает, на варианте, когда в случае ошибки ему будут поступать exception-s.
Какого типа обработка? Параллельная или конкурентная?
Главный поток ждёт результата или продолжает работать переодически проверяя сообщения? Какое вообще взаимодействие с их кодом?
Как уже выше сказали, нужно перехватывать исключения и передавать в другой поток через exception_ptr.
Если подходят promise + future — то там вся передача уже реализована, смотри std/boost::promise::set_exception.
AG>ПРИМЕЧАНИЕ: AG>Мы все пишем на MSVC-2015, однако Заказчик настаивает только на применении стандарта C++03 AG>В то же время, мы широко используем boost и STL. AG>С этими библиотеками Заказчик хорошо знаком.
В Boost для C++03 есть и exception_ptr, и promise+future.
Здравствуйте, VTT, Вы писали:
VTT>Ну в таких ситуациях обычная практика наверное перехватывать в рабочем потоке все исключения, складывая их в std::exception_ptr, а потом кидать в основном потоке, когда тот полезет проверять состояние (запрашивать результат) у этого рабочего потока.
Это интересно (только поддерживается начиная от C++11).
>>настаивает только на применении стандарта C++03 VTT>А чем это аргументируется?
Не хотят, возможно из-за того, что их система где-то завязана на старые проекты.
Re[2]: Передать ошибку "наверх" из многопоточнй библиотеки
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Какого типа обработка? Параллельная или конкурентная?
да — параллельная EP>Главный поток ждёт результата или продолжает работать переодически проверяя сообщения?
планирую сделать цикл ожидания (с прокачкой windows-messages) проверяя установку Event — при готовности результатов расчёта.
Какое вообще взаимодействие с их кодом?
они вызвали метод, на который у меня запустилась многопоточная параллельная обработка, после чего этот метод ждёт результат
EP>Как уже выше сказали, нужно перехватывать исключения и передавать в другой поток через exception_ptr. EP>Если подходят promise + future — то там вся передача уже реализована, смотри std/boost::promise::set_exception.
посмотрю — может это как раз то, что требуется...
EP>В Boost для C++03 есть и exception_ptr, и promise+future.
Спасибо, уважаемый Evgeny.Panasyuk, буду изучать этот вариант!
Re: Передать ошибку "наверх" из многопоточнй библиотеки
Здравствуйте, AlexGin, Вы писали:
AG>Пока мы планируем ввести глобальный флаг (скорее даже Event), который устанавливаем при ошибке. AG>Естественно, этот глобальный (либо статический) объект мы защитим критической секцией. AG>Далее, код, выполняемый в головном потоке "на нашей стороне" будет сканировать этот Event (с прокачкой windows-messages) и там уже, AG>если имела место проблема, выполнять throw...
Как вариант — использовать QueueUserAPC из потока, в котором произошло исключение.
Ждущий поток должен находиться в Alertable-ожидании (WaitForSingleObjectEx c bAlertable = TRUE).
Re[3]: Передать ошибку "наверх" из многопоточнй библиотеки
Здравствуйте, AlexGin, Вы писали:
AG>они вызвали метод, на который у меня запустилась многопоточная параллельная обработка, после чего этот метод ждёт результат
Под этот вариант как раз подходят std/boost::promise,future. Есть готовая обёртка которая сама запускает поток (в одном из режимов) и отдаёт future — std/boost::async.
EP>>В Boost для C++03 есть и exception_ptr, и promise+future. AG>Спасибо, уважаемый Evgeny.Panasyuk, буду изучать этот вариант!
Это всё разбирается в книжке C++ Concurrency in Action (от автора Boost.Thread)
Здравствуйте, AlexGin, Вы писали:
AG>Пока мы планируем ввести глобальный флаг (скорее даже Event), который устанавливаем при ошибке.
Глобальный флаг использовать не нужно. Твоя функция возвращает клиенту future, на своей стороне оставляешь связанный с ним promise. При ловле исключений заполняешь список исключений в этой своей promise; этот список будет доступен клиенту в его future как aggregate exception. Он либо опрашивает свою future на предмет IsCompleted/IsFailed/GetException(), либо зовёт GetResult() и ловит этот aggregate exception.
Глаза у меня добрые, но рубашка — смирительная!
Re[4]: Передать ошибку "наверх" из многопоточнй библиотеки
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>В Boost для C++03 есть и exception_ptr, и promise+future. EP>Это всё разбирается в книжке C++ Concurrency in Action (от автора Boost.Thread)
Огромное спасибо, уважаемый Evgeny.Panasyuk, — нашёл это