2017-10-19 146 views
0

我试图正确地终止命令结束进程和子进程

c := exec.Command("omxplayer", "video.mp4") 
c.Start() 

// send kill signal to terminate command at later stage 
time.Sleep(4*time.Second) 
c.Process.Kill() 
c.Wait() // should wait for program to fully exit 

// start again with new video 
c := exec.Command("omxplayer", "video2.mp4") 
c.Start() 

我想杀死我的树莓丕当前omxplayer过程,这样我就可以开始再次用一个新的视频。

一旦我发送了Kill信号,我打电话c.Wait()等待当前命令结束后再开始一个新的命令。

问题是第一个命令没有停止,但是下一个命令仍在启动。所以我最终同时播放了多个视频。

+2

'omxplayer'可能是派生一个新的进程。如果是这种情况,您可能不得不搜索其pid,以表明它是否没有提供关闭它的机制。 – JimB

+0

使用'pstree -p'查看'omxplayer'(如果有)分叉的进程。 – putu

+0

父进程也可能需要清理,但是您不会通过发送SIGKILL来让它进行清理。看看SIGTERM或SIGINT会发生什么。 – JimB

回答

1

omxplayer正在分岔一个新的过程。特别是对于omxplayer,我可以将“q”字符串发送到它的StdinPipe。这就像按下键盘上的q键,退出程序,结束双方的父母和孩子的过程:

c := exec.Command("omxplayer", "video.mp4") 
c.Start() 
p := c.StdinPipe() 
_, err := p.Write([]byte("q")) // send 'q' to the Stdin of the process to quit omxplayer 

c.Wait() // should wait for program to fully exit 

// start again with new video 
c := exec.Command("omxplayer", "video2.mp4") 
c.Start() 

另一种更普遍的选择是创建一个进程组同时与父进程和子进程并杀死:

c := exec.Command("omxplayer", "video.mp4") 
// make the process group id the same as the pid 
c.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} 
c.Start() 

// sending a negative number as the PID sends the kill signal to the group 
syscall.Kill(-c.Process.Pid, syscall.SIGKILL) 

c.Wait() 

基于this Medium post