Есть ли способ для пула потоков отменить выполняемую задачу? Еще лучше, есть ли безопасная альтернатива для отмены непрозрачных вызовов функций по запросу в thread_pools?
Убивать весь процесс - плохая идея, а использование собственного дескриптора для выполнения pthread_cancel
или аналогичного API - только в крайнем случае.
Дополнительно
Бонус, если отмена немедленная, но допустима, если у отмены есть какое-то временное ограничение «гарантии» (например, отмена в течение 0,1 секунды выполнения рассматриваемого потока)
Подробнее
Я не ограничен использованием Boost.Thread.thread_pool
или какой-либо конкретной библиотеки. Единственным ограничением является совместимость с C ++ 14 и способность работать как минимум на ОС на базе BSD и Linux.
Задачи обычно связаны с обработкой данных, предварительно компилируются и загружаются динамически с использованием C-API (extern "C"
) и, следовательно, являются непрозрачными объектами. Цель состоит в том, чтобы выполнять сложные вычислительные задачи с возможностью отмены их, когда пользователь отправляет прерывания.
Во время запуска, thread_id для конкретной задачи известен, и, таким образом, к некоторому API можно обратиться за дополнительной информацией, еслитребуется.
Отказ от ответственности
Я знаю, что использование ручных ручных нитей для отмены / выхода нитей не рекомендуется и является признаком плохого дизайна. Я также не могу изменить функции, используя boost::this_thread::interrupt_point
, но могу обернуть их в лямбды / другие конструкции, если это поможет. Я чувствую, что это сложная ситуация, поэтому альтернативные предложения приветствуются, но они должны быть минимально навязчивыми в существующей функциональности и могут быть драматичными по своему объему для обсуждаемого набора функций.
РЕДАКТИРОВАТЬ:
Уточнение
Я думаю, это должно было быть в разделе «Подробнее», но я хочу, чтобы он оставался отдельным, чтобы показать, что существующие 2 ответа основаны на ограниченной информации. Прочитав ответы, я вернулся к чертежной доске и придумал следующие «ограничения», поскольку поставленный вопрос был слишком общим. Если я хочу опубликовать новый вопрос, пожалуйста, дайте мне знать.
Мой интерфейс обещает ввод "const" (не изменяемый ввод в стиле функционального программирования), используя при необходимости mutexes / copy-by-value и проходя мимоconst&
(и ожидал, что поток будет вести себя хорошо).
Я также неправильно использовал термин «произвольный», поскольку задания не являются произвольными (эмпирически говоря) и имеют следующие ограничения:
- некоторые, которые загружают из "интернета", уже используют "условную переменную"
- , не нарушающие правильность const
- могут порождать другие потоки, но они не должны переживать родительский
- может использовать мьютекс, но они не могут существовать вне тела функции
- вывод через
atomic<shared_ptr>
, передаваемый в качестве аргумента - чистые функции (без общего состояния с внешним) **
- ** может быть лямбда-связыванием функтора, и в этом случае функция должна убедиться, что ее структуры данных не повреждены (как обычно, состояние 1 или 2
atomic<inbuilt-type>
). Обычно внутреннее состояние запрашивается из внешней базы данных (подобная архитектура, как cookie + веб-сервер, и вкладка / браузер может быть закрыта в любое время)
Эти ограничения не записываются как контракт илиничего, а точнее я обобщил на основе «модулей», используемых в настоящее время. Задания являются произвольными с точки зрения того, что они могут сделать: GPU / CPU / Internet - все это честно.
Невозможно вставить периодическую проверку из-за интенсивного использования библиотеки. Библиотеки (не принадлежащие нам) не были предназначены для периодической проверки переменной условия, поскольку это повлекло бы за собой снижение производительности в общем случае, и перезапись библиотек невозможна.