2 回答

TA貢獻1830條經驗 獲得超9個贊
我有時會遇到問題,您的代碼不會終止youtube-dl進程。視頻被轉換,但過程被保留。作為第一個指標,觀察進程計數,如下所示:
ps | grep youtube-dl | wc -l
可以讓子進程超時,對于一個子進程,這看起來像這樣:
package main
import (
"bytes"
"fmt"
"os/exec"
"time"
)
func main() {
// Sleep is used, so we can control how long it runs.
cmd := exec.Command("sleep", "2")
// Use a bytes.Buffer to get the output
var buf bytes.Buffer
cmd.Stdout = &buf
cmd.Start()
// Use a channel to signal completion so we can use a select statement
done := make(chan error)
go func() { done <- cmd.Wait() }()
// Start a timer, should be higher for your video conversion,
// I suggest you use a value that fits both your videos and server capabilities
timeout := time.After(2 * time.Second)
// The select statement allows us to execute based on which channel
// we get a message from first.
select {
case <-timeout:
// Timeout happened first, kill the process and print a message.
cmd.Process.Kill()
fmt.Println("Command timed out")
case err := <-done:
// Command completed before timeout. Print output and error if it exists.
fmt.Println("Output:", buf.String())
if err != nil {
fmt.Println("Non-zero exit code:", err)
}
}
}
在你的情況下,你可以更換
ffmpeg.Start()
youtubevideo.Start()
youtube.Start()
ffmpeg.Wait()
youtubevideo.Wait()
youtube.Wait()
和
ffmpeg.Start()
youtubevideo.Start()
youtube.Start()
commands := 3
done := make(chan error)
go func() { done <- ffmpeg.Wait() }()
go func() { done <- youtubevideo.Wait() }()
go func() { done <- youtube.Wait() }()
timeout := time.After(1 * time.Hour)
Loop:
for {
select {
case <-timeout:
ffmpeg.Process.Kill()
youtubevideo.Process.Kill()
youtube.Process.Kill()
log.Println("Conversion timed out")
break Loop
case err := <-done:
if err != nil {
log.Println("Non-zero exit code:", err)
}
commands = commands - 1
if commands == 0 {
break Loop
}
}
}

TA貢獻1790條經驗 獲得超9個贊
因此,經過一些調試并在凱文的回答的幫助下。成功后好像youtube-dl沒有關閉。
鑒于如果ffmpeg完成,那么讓youtube-dl實例運行沒有任何意義,并且由于Wait()函數正在等待youtube-dl完成,但它似乎從未發送完成信號,所以我繼續并不得不添加一個 kill 來殺死子子進程。
所以我不得不添加改變這個
ffmpeg.Start()
youtubevideo.Start()
youtube.Start()
ffmpeg.Wait()
youtubevideo.Wait()
youtube.Wait()
對此
youtube.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
youtubevideo.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
ffmpeg.Start()
youtubevideo.Start()
youtube.Start()
ffmpeg.Wait()
syscall.Kill(-youtube.Process.Pid, syscall.SIGKILL)
syscall.Kill(-youtubevideo.Process.Pid, syscall.SIGKILL)
youtubevideo.Wait()
youtube.Wait()
請注意,因為它似乎產生了某種子子youtube.Process.Kill()進程,實際上并沒有殺死該進程,這就是我必須使用的原因syscall,而且Setpgid: true
- 2 回答
- 0 關注
- 1153 瀏覽
添加回答
舉報