Jump to content

Program termination: Difference between revisions

→‎{{header|Go}}: added more techniques, removed note on error code values as this is not specified for Go.
({{header|UNIX Shell}})
(→‎{{header|Go}}: added more techniques, removed note on error code values as this is not specified for Go.)
Line 258:
 
=={{header|Go}}==
Operating system resources such as memory and file handles are generally released on exit automatically, but this is not specified in the language definition. Proceses started with os.StartProcess or exec.Run are not automatically terminated by any of the techniques below and will continue to run after the main program terminates.
<lang go>import "os"
===Return statement===
Basically, a return statement executed from anywhere in main() terminates the program.
<lang go>func main() {
if problem {
return
}
}</lang>
Deferred functions are run when the enclosing function returns, so in the example below, function <tt>paperwork</tt> is run. This is the idiomatic mechanism for doing any kind of necessary cleanup.
 
Other goroutines are terminated unceremoniously when <tt>main</tt> returns. Below, <tt>main</tt> returns without waiting for <tt>pcj</tt> to complete.
 
The tantalizingly named <tt>SetFinalizer</tt> mechanism is also not invoked on program termination. It is designed for resource reclamation in long-running processes, not for program termination.
 
Returns from functions other than main do not cause program termination. In particular, return from a goroutine simply terminates that one goroutine, and not the entire program.
<lang go>package main
 
import (
"fmt"
"runtime"
"time"
)
 
const problem = true
 
func main() {
fmt.Println("main program start")
 
// this will get run on exit
defer paperwork()
 
// this will not run to completion
go pcj()
 
// this will not get run on exit
rec := &requiresExternalCleanup{"external object"}
runtime.SetFinalizer(rec, cleanup)
 
if problem {
fmt.Println("main program returning")
return
}
}
 
func paperwork() {
fmt.Println("i's dotted, t's crossed")
}
 
func pcj() {
fmt.Println("there's uncle Joe")
time.Sleep(1e10)
fmt.Println("movin kinda slow")
}
 
type requiresExternalCleanup struct {
id string
}
 
func cleanup(rec *requiresExternalCleanup) {
fmt.Println(rec.id, "cleanup")
}</lang>
Output:
<pre>
main program start
main program returning
there's uncle Joe
i's dotted, t's crossed
</pre>
===Os.Exit===
Os.Exit causes its argument to be returned to the operating system as a program exit code. Unlike the return statement, library function os.Exit exits promptly and does not run deferred functions.
<lang go>func main() {
fmt.Println("main program start")
 
// this will not get run on os.Exit
defer func() {
fmt.Println("deferred function")
}()
 
if problem {
fmt.Println("main program exiting")
os.Exit(-1)
}
}</lang>
Output:
<pre>
main program start
main program exiting
</pre>
===Panic===
Panics have some similarities to exceptions in other languages, including that there is a recovery mechanism allowing program termination to be averted. When the program terminates from panic however, it prints the panic value and then a stack trace for all goroutines.
 
Like the return statement, panic runs deferred functions. It run functions deferred from the current function, but then proceeds to unwind the call stack of the goroutine, calling deferred functions at each level. It does this only in the goroutine where panic was called. Deferred functions in other goroutines are not run and if panicking goes unrecovered and the program terminates, all other goroutines are terminated abruptly.
<lang go>func pcj() {
fmt.Println("at the junction")
defer func() {
fmt.Println("deferred from pcj")
}()
panic(10)
}
 
iffunc problemmain() {
fmt.Println("main program start")
os.Exit(integerErrorCode)
defer func() {
/* conventionally, error code 0 or EXIT_SUCCESS is the code for "OK",
fmt.Println("deferred from main")
EXIT_FAILURE is the code for "not OK",
}()
while anything else is a problem that is implementation-defined */
go pcj()
time.Sleep(1e9)
fmt.Println("main program done")
}</lang>
Output:
<pre>
main program start
at the junction
deferred from pcj
panic: 10
(and the stack trace follows)
</pre>
 
=={{header|Haskell}}==
1,707

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.