About Unix processes and signals
a process is an execution environment that contains instructions, user-data and system-data parts, and other kinds of resources that are obtained during runtime, whereas a program is a file that contains instructions and data, which are used for initializing the instruction and user-data parts of a process.
Process management
Go is not that good at dealing with processes and process management in general.
[maxwell@MaxwellDBA goproject]$ vim listProcess.go
[maxwell@MaxwellDBA goproject]$ go run listProcess.go | head -3
/usr/bin/ps
PID TTY STAT TIME COMMAND
1 ? Ss 2:38 /usr/lib/systemd/systemd --switched-root --system --deserialize 17
[maxwell@MaxwellDBA goproject]$ cat listProcess.go
package main
import (
"fmt"
"os"
"os/exec"
"syscall"
)
func main() {
PS, err := exec.LookPath("ps")
if err != nil {
fmt.Println(err)
}
fmt.Println(PS)
command := []string{"ps", "-a", "-x"}
env := os.Environ()
err = syscall.Exec(PS, command, env)
if err != nil {
fmt.Println(err)
}
}
[maxwell@MaxwellDBA goproject]$
A simple signal handler in Go
[maxwell@MaxwellDBA goproject]$ vim h1s.go
[maxwell@MaxwellDBA goproject]$ go build h1s.go
[maxwell@MaxwellDBA goproject]$ ./h1s
............................................^CInterrupt
Got Interrupt
...^CInterrupt
Got Interrupt
^CInterrupt
Got Interrupt
.1
[maxwell@MaxwellDBA goproject]$ cat h1s.go
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func handleSignal(signal os.Signal){
fmt.Println("Got", signal)
}
func main() {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)
go func() {
for {
sig := <-sigs
fmt.Println(sig)
handleSignal(sig)
}
}()
for {
fmt.Printf(".")
time.Sleep(10 * time.Second)
}
}
[maxwell@MaxwellDBA goproject]$
Handling three different signals!(SIGTERM,SIGINT,and SIGHUP signals)
maxwell@MaxwellDBA goproject]$ vim h2s.go
[maxwell@MaxwellDBA goproject]$ go build h2s.go
[maxwell@MaxwellDBA goproject]$ ./h2s
.....
[maxwell@MaxwellDBA goproject]$ cat h2s.go
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func handleSignal(signal os.Signal){
fmt.Println("* Got:", signal)
}
func main() {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
go func() {
for {
sig := <-sigs
switch sig {
case os.Interrupt:
handleSignal(sig)
case syscall.SIGTERM:
handleSignal(sig)
case syscall.SIGHUP:
fmt.Println("Got:", sig)
os.Exit(-1)
}
}
}()
for {
fmt.Printf(".")
time.Sleep(10 * time.Second)
}
}
[maxwell@MaxwellDBA goproject]$
Catching every signal that can be handled
[maxwell@MaxwellDBA goproject]$ vim catchAll.go
[maxwell@MaxwellDBA goproject]$ go build catchAll.go
[maxwell@MaxwellDBA goproject]$ ./catchAll
......^C* Got: Interrupt
[maxwell@MaxwellDBA goproject]$ cat catchAll.go
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func handleSignal(signal os.Signal){
fmt.Println("* Got:", signal)
}
func main() {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs)
go func() {
for {
sig := <-sigs
switch sig {
case os.Interrupt:
handleSignal(sig)
case syscall.SIGTERM:
handleSignal(sig)
os.Exit(-1)
case syscall.SIGUSR1:
handleSignal(sig)
default:
fmt.Println("Ignoring:", sig)
}
}
}()
for {
fmt.Printf(".")
time.Sleep(10 * time.Second)
}
}
[maxwell@MaxwellDBA goproject]$