mactsouk/mastering-Go-3rd

Why is `os.Exit` called in `signals.go`

Vyom-Yadav opened this issue · 3 comments

From:

case syscall.SIGINFO:
handleSignal(sig)
// do not use return here because the goroutine will exit
// but the time.Sleep() will continue to work!
os.Exit(0)

Why is os.Exit() called for SIGINFO. I tried this locally with SIGUSR1 and executing:

$ kill -USR1 <pid>

caused the complete process to exit not just the go routine. The <pid> didn't exist anymore and the process had terminated.
When I tried the same example by commenting out os.Exit(), it worked perfectly fine and the for loop was still continuing and the go routine hadn't exited.

I am on Ch-06 right now so my knowledge about goroutines and channels is limited.

cc @mactsouk Would really appreciate some clarification on this.

However, the result differed when I pressed ^Z (SIGTSTP) and then tried to send SIGUSR1 to the process.

$ go run unixsignals/signal.go
Process ID: 82121
+^CExecution time: 9.756046359s
Caught: urgent I/O condition
+^CExecution time: 12.809259096s
^ZCaught: stopped

[1]  + 82007 suspended  go run unixsignals/signal.go
$ ps aux | grep $USER | grep signal
vyom       82007  0.0  0.1 1979092 17944 pts/10  Tl   19:21   0:00 go run unixsignals/signal.go
vyom       82121  0.0  0.0 710556  1664 pts/10   Sl   19:21   0:00 /tmp/go-build86970276/b001/exe/signal
vyom       82402  0.0  0.0 222412  2304 pts/6    S+   19:22   0:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox signal

We can see it's still running and printing + on the terminal (not under the same command, on the next command).

Now if I send a USR1 signal to it: (from another terminal, basically another process)

$ kill -USR1 82121
$ ps aux | grep $USER | grep signal
vyom       82007  0.0  0.1 1979092 17944 pts/10  Tl   19:21   0:00 go run unixsignals/signal.go
vyom       82121  0.0  0.0      0     0 pts/10   Z    19:21   0:00 [signal] <defunct>
vyom       82670  0.0  0.0 222412  2176 pts/6    S+   19:24   0:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox signal

It goes in a defunct state. I cannot recreate the behavior in the book; I would really appreciate your help on this one.

$ pstree -hp | grep signal
           |               |                   |             |-code(20242)-+-code(20257)-+-zsh(81692)---go(82007)-+-signal(82121)

[signal] <defunct> is the child process of go run unixsignals/signal.go

@Vyom-Yadav This is a decision that you can change. Feel free to use return if you want.
However, in my tests, return does not terminate the entire program. This is the reason for using os.Exit in this case.