Answer the question
In order to leave comments, you need to log in
What is the problem with sending a signal to a child process?
The third day I can not google. Everything is very simple. There is a parent process which to produce child process. Later, the parent process must kill the child. But not through KIll, but send a signal for a correct termination. The child process catches the signal and exits.
The simplest examples:
Parent (parent.go)
package main
import (
"fmt"
"os"
"os/exec"
"syscall"
"time"
)
func main() {
// Запускаем дочерний процесс
cmd := exec.Command("./child")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Start()
if err != nil {
fmt.Println("Child process not starting")
os.Exit(1)
}
pid := cmd.Process.Pid
fmt.Println("Child PID:", pid)
// Отправляем сигнал о желании завершить процесс
err = cmd.Process.Signal(syscall.SIGTERM)
if err != nil {
fmt.Println("Signal not sent:", err)
}
// Тикаем 10 секунд, в ожидании завершения процесса
tick := time.NewTicker(1 * time.Second)
i := 1
for range tick.C {
_, err := os.FindProcess(pid)
if err != nil {
break
}
if i == 10 {
break
}
fmt.Println(i)
i++
}
tick.Stop()
// Убиваем процесс если он так и не получил сигнал!
err = cmd.Process.Kill()
if err != nil {
fmt.Println("Child process not die")
}
fmt.Println("Exiting")
}
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
// Слушаем сигнал
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGTERM)
// Зависаем в ожидании сигнала
<-c
signal.Stop(c)
fmt.Println("Child finish!")
}
Answer the question
In order to leave comments, you need to log in
Sorry for being direct, but the problem is your lack of knowledge of the materiel.
What to read on the topic: Zombie process , as well as Docker and the PID 1 zombie reaping problem .
And now closer to your example.
Bottom line: both SITERM and SIGKILL you successfully kill the child process, after which it turns into a zombie process, that is, it still hangs in memory under its PID, waiting for reaping (wait() system call from the parent process). After the parent process ends, our zombie child is adopted by the init process, which reaps it.
If you run your programs as you posted them, and write ps while ticking, you will see the following picture:
459 ttys000 0:00.03 -bash
498 ttys000 0:00.00 ./parent
499 ttys000 0:00.00 (child)
The fact that child is in parentheses just means that the process was stopped (that is, it made the exit() system call) and is waiting for reaping (when the result of exit() is read by wait()). time.Sleep(10 * time.Second)
and immediately after the output of the child's PID we type to look at what is happening in the processes, we will see the following picture:459 ttys000 0:00.04 -bash
510 ttys000 0:00.00 ./parent
511 ttys000 0:00.00 ./child
Compare with how it appears in processes after it has been killed. cmd.Process.Wait()
, then your ticker cycle will still, perhaps, still be spinning if a new process with such a PID has appeared in the system, but if we look at ps, we will see that our child is no longer there at all:459 ttys000 0:00.05 -bash
536 ttys000 0:00.01 ./parent
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question