убить буст поток через n секунд - PullRequest
3 голосов
/ 27 октября 2010

Я ищу лучший способ решить следующую проблему (c ++). У меня есть функция, данная какой-то платформой, которая возвращает объект. Иногда это занимает всего лишь миллисекунды, но в некоторых случаях это занимает минуты. Поэтому я хочу остановить выполнение, если это займет больше времени, чем, скажем, 2 секунды. Я думал о том, чтобы сделать это с буст-нитями. Важное замечание: если функция возвращается быстрее, чем за 2 секунды, программа не должна ждать. Итак, я думал о 2 потоках:

1.thread: execute function a       
2.thread: run timer                
if(thread 2 exited bevore thread 1) kill thread 1 
else do nothing

Я немного борюсь с практической реализацией. Особенно,

  • как мне вернуть объект из дочернего вспомогательного потока в основной поток?
  • как мне убить поток в boost?
  • Является ли моя идея даже хорошей, есть ли лучший способ решить проблему в c ++ (с надстройкой или без)?

Ответы [ 3 ]

2 голосов
/ 27 октября 2010

Что касается ожидания, просто используйте thread::timed_join() внутри основного потока, это вернет false, если поток не завершился в течение заданного времени.

Уничтожение потока невозможно, если ваша сторонняя библиотека не знает о потоках boost:. Кроме того, вы почти наверняка не захотите «убить» поток, не предоставив функции возможность очистки.

Я бы посоветовал вам подождать, скажем, 2 секунды, а затем продолжить с каким-то сообщением об ошибке, позволяя каркасной функции завершить свою работу и просто игнорировать результат, если он пришел слишком поздно.

Что касается возврата значения, я бы предложил что-то вроде

struct myfunction {
   MyObj returnValue;
   void operator() () { 
     // ... 
     returnValue = theComputedReturnValue;
   }
};

// ...
myfunction f;
boost::thread t = boost::thread(boost::ref(f));
t.join(); // or t.timed_join()...
use(f.returnValue); 
// ...
0 голосов
/ 27 октября 2010

Расширение того, что Джеймс сказал выше, «убить нить» - это такой суровый термин! :) Но прерывание также не так просто, как правило, с буст-потоками, должна быть точка прерывания, где работающий поток может быть прерван. Существует набор этих прерываемых функций (к сожалению, они специфичны для повышения), таких как ожидание / сон и т. Д. Один из вариантов, который у вас есть, находится в первом потоке, свободно разбрасывает interrupt_points (). Так, что когда вы вызываете interrupt (), как только поток 2 умирает, при следующем interrupt_point () поток 1 сгенерирует исключение.

Потоки находятся в одном и том же пространстве процесса, поэтому вы можете иметь общее состояние между несколькими потоками, пока существует синхронизированный доступ к этому общему состоянию.

РЕДАКТИРОВАТЬ: только что заметил, что ОП уже рассмотрел это ... оставит ответ в любом случае, я думаю ...

0 голосов
/ 27 октября 2010

Я делал что-то похожее в прошлом, и это работает (хотя и не идеально).Чтобы получить возвращаемое значение, просто «поделитесь» переменной (это может быть просто указатель (изначально ноль) на возвращаемое значение или полный объект с состоянием и т. Д.) И заставьте ваш поток прочитать / обновить его.Не забудьте заглушить это необходимо.Это должно быть довольно просто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...