didil
didil

Reputation: 715

How can you cleanly terminate a process in C++11?

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

Answers (3)

Serge Ballesta
Serge Ballesta

Reputation: 149155

The real solution would be to deal with the cause and not the symptom:

  • symptom: run function never ends
  • cause: a communication request never ends

Most 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

didil
didil

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

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

Related Questions