Reputation: 715
I wonder if there is a good way to terminate my process written in C++11 after a while?
In my process I have a main class with a pure virtual function run()
running the main program that could be blocked in communication processes. I want my run()
function to be forced to finish after a while (even if blocked) and the destructor of my main class (and all the destructors of the members) to be called.
Now I have a timer that call std::terminate
via a callback.
namespace Timer
{
void start(Duration time, function<void()> task)
{
thread([time, task]() {
this_thread::sleep_for(time);
task();
}).detach();
}
}
Upvotes: 1
Views: 866
Reputation: 149155
The real solution would be to deal with the cause and not the symptom:
run
function never endsMost communication (input) functions are interruptible, or have native timeouts. If your communication routines have no native timeouts, you could (maybe) wrap them in a way using an alarm
Posix call that should cleanly interrupt them and allow the run function to cleanly exit.
You just have to pay attention to the fact that alarm
uses signal under the hood so you must not block SIG_ALRM
, but you can use it to install a signal handler that stores somewhere that is has been called.
IMHO, it will be simpler, cleaner, and with a better separation of concern than directly terminating the program with std::terminate
.
Above only deals with the case where run
never ends. If you want to limit the time it runs, you should identify interruptible places in your code where you test if allowed run time is exhausted, and consistently put timeouts on all possibly blocking communication IO.
Upvotes: 2
Reputation: 715
The best solution is to wrap run()
in a thread.
std::thread([&]()
{
run();
finish.notify_all();
}).detach();
std::unique_lock<std::mutex> lock(waitFinish);
finish.wait_for(lock, time);
Upvotes: 1
Reputation: 1
I guess you are on Linux or some other POSIX system. Event loops and polling are not standardized in C++11 and need operating system specific things.
Your event loop should never be blocked for a long time. It should have some finite -and not too big- timeout. On POSIX, use poll(2) in your event loop with a reasonable timeout (e.g. a second). Alternatively, use a pipe (internal to the process) to trigger the event loop (so some other thread -or even a signal handler- would write(2) on that pipe, and the event loop would poll it and read
it, and might stop, hence returning from run
)
See also this and that for related hints.
Upvotes: 1