Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between std::quick_exit and std::abort and why was std::quick_exit needed?

C++11 introduces a new way of finishing program execution—std::quick_exit.

Quoting the N3242 18.5 (p. 461):

[[noreturn]] void quick_exit(int status) noexcept; 

Effects: Functions registered by calls to at_quick_exit are called in the reverse order of their registration, except that a function shall be called after any previously registered functions that had already been called at the time it was registered. Objects shall not be destroyed as a result of calling quick_exit. If control leaves a registered function called by quick_exit because the function does not provide a handler for a thrown exception, terminate() shall be called. [ Note: at_quick_exit may call a registered function from a different thread than the one that registered it, so registered functions should not rely on the identity of objects with thread storage duration. — end note ] After calling registered functions, quick_exit shall call _Exit(status). [ Note: The standard file buffers are not flushed. See: ISO C 7.20.4.4. — end note ]

As the definition of std::abort(void) and std::_Exit(int status) differ only in ability to pass the status to the parent process, it raises my question.

Does it mean that the only difference in semantics between std::quick_exit and std::abort are that std::quick_exit calls functions registered using std::at_quick_exit and allows to set the returned status?

What was the rationale for introducing this function?

like image 255
Rafał Rawicki Avatar asked Mar 18 '12 13:03

Rafał Rawicki


People also ask

What does std :: abort do?

std::abort()Causes abnormal program termination unless SIGABRT is being caught by a signal handler passed to std::signal and the handler does not return.

What is abort C++?

abort() -- Stop a Program The abort() function causes an abnormal end of the program and returns control to the host environment. Like the exit() function, the abort() function deletes buffers and closes open files before ending the program.

Does abort call destructors?

If you call abort anywhere in a program, no destructors are called, not even for variables with a global scope.


2 Answers

There's a good write-up available here, I'll just summarize it. This feature was added to specifically deal with the difficulty of ending a program cleanly when you use threads. By nature, the exit is started by a highly asynchronous event, the user closing the user interface, the admin shutting down the machine, etcetera. This happens without regard to the state of the threads the program started, they are almost always in a highly unpredictable state.

In an ideal world, the program's main() function asks the threads to exit, typically by signaling an event, waits for the threads to end and then exits main() for a clean shutdown through exit(). That ideal is however very hard to achieve. A thread could be buried deep inside a system call, say, waiting for some I/O to complete. Or it is blocking on a synchronization object that needs to be signaled by another thread in the right order. The outcome is rarely pleasant, real programs often deadlock on exit. Or crash when the shutdown order is unexpected.

There's a simple and very tempting workaround for this problem: call _exit() instead. Kaboom, program ended, the operating system brooms up the shrapnel. But clearly without any cleanup at all, very messy sometimes with artifacts like a half-written file or an incomplete dbase transaction.

std::quick_exit() offers the alternative. Similar to _exit() but with still the option to execute some code, whatever was registered with at_quick_exit.

like image 143
Hans Passant Avatar answered Oct 06 '22 22:10

Hans Passant


The rationale for std::quick_exit is discussed in N1327 and N2440. The key differences between quick_exit, _Exit, and exit concerns the handling of static destructors and flushing critical information to stable storage:

  • std::_Exit: doesn't execute static destructors or flush critical IO.
  • std::exit: executes static destructors and flushes critical IO.
  • std::quick_exit: doesn't execute static destructors, but does flush critical IO.

(As mentioned, std::abort just sends SIGABRT.)

like image 25
一二三 Avatar answered Oct 06 '22 22:10

一二三