Есть клиент-серверная архитектура. Задача стоит в том, как ограничить время ответа сервера и прервать выполнение долгой задачи.
Пример:
class ITask
{
public:
virtual void run() = 0;
};
таски кладутся в очередь пула потоков (или потока, не важно) когда приходит запрос от клиента. Дальше таска выполняется и мы посылаем клиенту ответ.
Если таска выполняется больше, к примеру, 5-ти секунд, то надо прервать работу потока и послать клиенту ответ с ошибкой.
Есть ли готовые решения данной проблемы? Если нет, то как бы по грамотнее решить её своими велосипедами?
Re: Как ограничить время выполнения задачи в потоке?
Здравствуйте, Аноним, Вы писали:
А>Есть ли готовые решения данной проблемы? Если нет, то как бы по грамотнее решить её своими велосипедами?
Добавить в пул потоков функционал отслеживающий потоки живущие уже больше 5 секунд и прибивающий их.
Добавить дополнительный поток с аналогичным функционалом.
Помле того как поток был прибит, отсылаешь клиенту ответ о проблеме.
Re: Как ограничить время выполнения задачи в потоке?
Здравствуйте, Аноним, Вы писали:
А>Есть клиент-серверная архитектура. Задача стоит в том, как ограничить время ответа сервера и прервать выполнение долгой задачи. А>Пример: А>
А>таски кладутся в очередь пула потоков (или потока, не важно) когда приходит запрос от клиента. Дальше таска выполняется и мы посылаем клиенту ответ. А>Если таска выполняется больше, к примеру, 5-ти секунд, то надо прервать работу потока и послать клиенту ответ с ошибкой. А>Есть ли готовые решения данной проблемы? Если нет, то как бы по грамотнее решить её своими велосипедами?
boost::asio + deadline_timer
Re: Как ограничить время выполнения задачи в потоке?
А>Если таска выполняется больше, к примеру, 5-ти секунд, то надо прервать работу потока и послать клиенту ответ с ошибкой. А>Есть ли готовые решения данной проблемы? Если нет, то как бы по грамотнее решить её своими велосипедами?
Если поток работает, а не висит в дедлоке, и ограничение на 5 секунд не совсем жёсткое, то можно воспользоваться приёмом, аналогичному применяемому в Boost.Thread: Interruption:
A running thread can be interrupted by invoking the interrupt() member function of the corresponding boost::thread object. When the interrupted thread next executes one of the specified interruption points (or if it is currently blocked whilst executing one) with interruption enabled, then a boost::thread_interrupted exception will be thrown in the interrupted thread. If not caught, this will cause the execution of the interrupted thread to terminate. As with any other exception, the stack will be unwound, and destructors for objects of automatic storage duration will be executed.
Этот метод позволяет корректно завершить поток в отличии от убийства потока системными вызовами, что чревато проблемами.
Re[2]: Как ограничить время выполнения задачи в потоке?
От:
Аноним
Дата:
26.03.13 08:42
Оценка:
Здравствуйте, Константин, Вы писали:
К>Если поток работает, а не висит в дедлоке, и ограничение на 5 секунд не совсем жёсткое
нельзя определить в дедлоке поток или нет. Нужно решение, которое бы работало для дедлоков тоже.
Re[3]: Как ограничить время выполнения задачи в потоке?
Здравствуйте, Аноним, Вы писали:
А>нельзя определить в дедлоке поток или нет. Нужно решение, которое бы работало для дедлоков тоже.
Если всё так плохо — вынести обработку задачи/задач в отдельный процесс и убивать целиком процесс. Убийство потока ставит под сомнение дальнейшую корректную работу всего приложения.
Re[4]: Как ограничить время выполнения задачи в потоке?
От:
Аноним
Дата:
26.03.13 14:16
Оценка:
Здравствуйте, Константин, Вы писали:
К>Здравствуйте, Аноним, Вы писали:
К>Если всё так плохо — вынести обработку задачи/задач в отдельный процесс и убивать целиком процесс. Убийство потока ставит под сомнение дальнейшую корректную работу всего приложения.
речь скорее идет не о классических дедлоках, вызванных примитивами синхронизации — вся логика там однопоточная. Речь идет о бесконечных циклах и подобных неприятностях.
Re[5]: Как ограничить время выполнения задачи в потоке?
Здравствуйте, Аноним, Вы писали:
А>речь скорее идет не о классических дедлоках, вызванных примитивами синхронизации — вся логика там однопоточная. Речь идет о бесконечных циклах и подобных неприятностях.
да какая разница. Все равно безопасно убить поток извне практически невозможно (ну или надо специально безопасно писать код в потоке — не дергая функций вроде malloc/free, не выделяя ресурсов и т.д.). Лучший способ, имхо, по аналогии с boost::thread (тебе уже советовали выше). Во все циклы можно напихать boost::inrettuption_point() (или как она там называется).
Если это невозможно — тогда отдельный процесс.
Re[5]: Как ограничить время выполнения задачи в потоке?
Здравствуйте, Аноним, Вы писали:
А>речь скорее идет не о классических дедлоках, вызванных примитивами синхронизации — вся логика там однопоточная. Речь идет о бесконечных циклах и подобных неприятностях.
Вы ожидаете какого-то волшебства? Волшебства не существует. Либо поток сам определяет, что задача выполняется слишком долго и завершает ее обработку, либо кто-то извне его прибивает. Варианты реализации возможны, но все они сводятся к одной из этих групп. Критерии Вам придется выбрать самому. Ну например, в безопасных местах записывать в переменную метку времени. Контролер периодически проверяет метку, и если она давно не изменялась, задача "зависла". А дальше — см. выше.
"Нормальные герои всегда идут в обход!"
Re[6]: Как ограничить время выполнения задачи в потоке?
Полностью корректно завершить — нельзя. Но если допустить некоторые 'приемлемые потери', то вполне себе можно грохнуть нитку... Память утечет, хэндлы утекути т.п., но кое-как приложение будет хромать дальше. Вот если поток завис в момент манипуляций с каким-либо общими для всего процесса данными, то тады ой...
... << RSDN@Home 1.2.0 alpha 5 rev. 1495>>
Let it be! — Давайте есть пчелу!
Re[7]: Как ограничить время выполнения задачи в потоке?
T>Полностью корректно завершить — нельзя. Но если допустить некоторые 'приемлемые потери', то вполне себе можно грохнуть нитку... Память утечет, хэндлы утекути т.п., но кое-как приложение будет хромать дальше. Вот если поток завис в момент манипуляций с каким-либо общими для всего процесса данными, то тады ой...
Вы из тех кто ставит SetUnhandledExceptionFilter и по приходу AV — просто пропускает зафэйлившийся опкод?
Как много веселых ребят, и все делают велосипед...