Скажем, у меня есть функция, чей прототип выглядит так, принадлежащий классу container_class
:
std::vector<int> container_class::func(int param);
Функция может вызывать или не вызывать бесконечный цикл на определенных входах; невозможно сказать, какие входные данные вызовут успех, а какие — бесконечный цикл. Функция находится в библиотеке, источник которой у меня нет, и я не могу ее изменить (это ошибка, и она будет исправлена в следующем выпуске через несколько месяцев, но сейчас мне нужен способ обойти ее), поэтому решения, которые изменяют функцию или класс, не будут работать.
Я пытался изолировать функцию с помощью std::async
а также std::future
и используя цикл while для постоянной проверки состояния потока:
container_class c();
long start = get_current_time(); //get the current time in ms
auto future = std::async(&container_class::func, &c, 2);
while(future.wait_for(0ms) != std::future_status::ready) {
if(get_current_time() - start > 1000) {
//forcibly terminate future
}
sleep(2);
}
Этот код имеет много проблем. Во-первых, я не могу принудительно прекратить std::future
объект (и поток, который он представляет).
В крайнем случае, если я не могу найти никакого другого решения, я могу изолировать функцию в ее собственном исполняемом файле, запустить ее, а затем проверить ее состояние и завершить ее соответствующим образом. Однако я бы предпочел не делать этого.
Как я могу сделать это? Есть ли лучший способ, чем то, что я делаю сейчас?
Вам не повезло, извините.
Во-первых, C ++ даже не гарантирует вам, что будет поток для будущего исполнения. Хотя было бы крайне сложно (вероятно, невозможно) реализовать все std::async
гарантии в одном потоке, нет прямого запрета на это, а также, конечно, нет никакой гарантии, что будет поток в async
вызов. Из-за этого нет способа отменить асинхронное выполнение.
Во-вторых, такого способа нет даже на самом низком уровне реализации потоков. В то время как pthread_cancel
существует, это не защитит вас от бесконечных циклов, не посещающих точки отмены, например.
Вы не можете произвольно убить поток в Posix, и модель потока C ++ основана на нем. Процесс действительно не может быть планировщиком своих собственных потоков, и, хотя иногда это является болью, это то, чем он является.
Других решений пока нет …