Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In go, is there a way to execute code on termination of the program?

I know you can define functions called init in any package, and these function will be executed before main. I use this to open my log file and my DB connection.

Is there a way to define code that will be executed when the program ends, either because it reaches the end of the main function or because it was interrupted ? The only way I can think of is by manually calling a deffered terminate function on each package used by main, but that's quite verbose and error prone.

like image 259
Fabien Avatar asked Mar 22 '13 09:03

Fabien


People also ask

How to stop running Go program?

Exit program If you want to quit your golang program, you can use os. Exit. This is part of the os module.

What does os exit do in Golang?

An exit code or an exit status is a number returned by a program to indicate whether a program has successfully executed or encountered an error. Typically, an exit code of 0 means that the program executes successfully. Any other numerical value between 1 and 125 (golang) shows the program encountered an error.

Which of the following package of Golang has the exit function to terminate a Golang program?

Here, we imported the "fmt" package to use the Printf() function and we also imported the "os" package to use the Exit() function. In the main() function, we used os. Exit() function to terminate the execution of the program.

What is defer in Golang?

In Golang, the defer keyword is used to delay the execution of a function or a statement until the nearby function returns. In simple words, defer will move the execution of the statement to the very end inside a function.


1 Answers

The C atexit functionality was considered by the Go developers and the idea of adopting it was rejected.

From one of the related thread at golang-nuts:

Russ Cox:

Atexit may make sense in single-threaded, short-lived programs, but I am skeptical that it has a place in a long-running multi-threaded server. I've seen many C++ programs that hang on exit because they're running global destructors that don't really need to run, and those destructors are cleaning up and freeing memory that would be reclaimed by the operating system anyway, if only the program could get to the exit system call. Compared to all that pain, needing to call Flush when you're one with a buffer seems entirely reasonable and is necessary anyway for correct execution of long-running programs.

Even ignoring that problem, atexit introduces even more threads of control, and you have to answer questions like do all the other goroutines stop before the atexit handlers run? If not, how do they avoid interfering? If so, what if one holds a lock that the handler needs? And on and on.

I'm not at all inclined to add Atexit.

Ian Lance Taylor:

The only fully reliable mechanism is a wrapper program that invokes the real program and does the cleanup when the real program completes. That is true in any language, not just Go.

In my somewhat unformed opinion, os.AtExit is not a great idea. It is an unstructured facility that causes stuff to happen at program exit time in an unpredictable order. It leads to weird scenarios like programs that take a long time just to exit, an operation that should be very fast. It also leads to weird functions like the C function _exit, which more or less means exit-but-don't-run-atexit-functions.

That said, I think a special exit function corresponding to the init function is an interesting idea. It would have the structure that os.AtExit lacks (namely, exit functions are run in reverse order of when init functions are run).

But exit functions won't help you if your program gets killed by the kernel, or crashes because you call some C code that gets a segmentation violation.

like image 94
zzzz Avatar answered Oct 21 '22 16:10

zzzz