2015-11-10 2 views
0

Интересно, есть ли способ прекратить мой процесс, написанный на C++ 11 через некоторое время?Как вы можете чисто завершить процесс в C++ 11?

В моем процессе у меня есть основной класс с чистой виртуальной функцией run(), управляющий основной программой, которая может быть заблокирована в процессах связи. Я хочу, чтобы моя функция run() была вынуждена закончить через некоторое время (даже если она заблокирована) и деструктор моего основного класса (и всех деструкторов членов).

Теперь у меня есть таймер, который вызывает std::terminate через обратный вызов.

namespace Timer 
{ 
    void start(Duration time, function<void()> task) 
    { 
     thread([time, task]() { 
      this_thread::sleep_for(time); 
      task(); 
     }).detach(); 
    } 
} 
+1

Если функция 'run()' не вернется, вы не сможете закончить программу в чистоте.Возможно, вы могли бы запустить 'run()' в потоке и вызвать 'thread :: detach()' на нем: будут вызваны основные деструкторы, но я бы не назвал его _clean_. – rodrigo

+1

У меня была эта проблема, тоже с программой, которая могла застрять в общении. Я добавил к нему библейский ритм, поэтому я знаю каждые X секунд (в моем случае каждые 45 секунд) сообщение будет получено и отправлено, а затем будет установлен тайм-аут минуты. Поэтому я никогда не попадаю в случай, когда я застреваю и жду сообщения. Конечно, худший случай заключался в том, что программе нужно было 45 секунд, чтобы закрыть, но она чиста! – Nidhoegger

+0

Если заблокирован (отсоединенный) поток, он не может быть изящно завершен без первого разблокирования. Вы должны управлять этим синтаксически с помощью _e.g._, используя wait/notify или периодически проверять статус с помощью 'wait_for' или аналогичного. – Snps

ответ

1

Лучшим решением является обертка run() в потоке.

std::thread([&]() 
{ 
    run(); 
    finish.notify_all(); 
}).detach(); 

std::unique_lock<std::mutex> lock(waitFinish); 
finish.wait_for(lock, time); 
1

Возможно, вы находитесь в Linux или какой-либо другой системе POSIX. Event loops и опрос не стандартизированы в C++ 11 и нуждаются в конкретных операционных системах.

Ваш цикл событий никогда не должен блокироваться в течение длительного времени. Он должен иметь некоторый конечный и не слишком большой тайм-аут. В POSIX используйте poll(2) в вашем цикле событий с разумным таймаутом (например, секундой). В качестве альтернативы, используйте pipe (внутри процесса), чтобы вызвать цикл событий (так что какой-то другой поток или даже обработчик сигналов будет write(2) на этом канале, и цикл событий будет опросить его и read его, и может остановиться, следовательно возвращение из run)

См. также this и that для соответствующих советов.

2

реального решение будет иметь дело с причиной, а не симптом:

  • симптом: run функция никогда не заканчивается
  • причину: запрос коммуникации никогда не заканчивается

Наиболее коммуникационные (входные) функции прерываются или имеют собственные тайм-ауты. Если ваши коммуникационные процедуры не имеют собственных тайм-аутов, вы можете (возможно) обернуть их способом, используя вызов alarm Posix, который должен их чисто прерывать и позволить функции запуска выполнить чистое завершение.

Вы просто должны обратить внимание на то, что alarm использует сигнал под капотом, так что вы не должны блокировать SIG_ALRM, но вы можете использовать его, чтобы установить обработчик сигнала, который хранит где который был вызван.

IMHO, это будет проще, чище и с лучшим разделением внимания, чем прямое завершение программы с помощью std::terminate.

Выше дело касается случая, когда run никогда не заканчивается. Если вы хотите ограничить время его запуска, вы должны идентифицировать в своем коде прерывистые места, где вы проверяете, разрешено ли время выполнения, и последовательно помещают таймауты во все возможные блокирующие сообщения IO.

+0

Ты не отвечаешь на мой вопрос. 'run()' завершается. Но это может занять больше времени, чем ожидалось. Я хочу заставить 'run()' закончить в случае, если он слишком длинный. Он может быть заблокирован в прочитанном сообщении или нет. – didil

 Смежные вопросы

  • Нет связанных вопросов^_^