我有一个用PHP编写的守护进程(不是最好的语言,但与我合作),它可以从队列中接收作业,并在需要完成任务时处理它们.对于每个新作业,我使用pcntl_fork()将作业分成一个子进程.在这个子进程中,然后我使用proc_open()来执行长时间运行的系统命令,用于音频转码,完成后直接返回给子进程.完成作业后,子进程将退出并由父进程清理.
为了让这个守护进程始终运行,我使用了暴发.这是我的upstart配置文件:
description "Audio Transcoding Daemon"
start on startup
stop on shutdown
# kill signal SIGCHLD
kill timeout 1200 # Don't force kill the process until it runs over 20 minutes
respawn
exec audio-daemon.php
Run Code Online (Sandbox Code Playgroud)
因为我想在分布式环境中使用这个守护进程,所以我希望能够在不中断任何正在运行的作业的情况下随时关闭服务器.为此,我已经在父进程上使用pcntl_signal()为SIGTERM,SIGHUP和SIGINT 实现了信号处理程序,它等待所有子进程在退出之前正常退出.孩子们也有信号处理程序,但他们会忽略所有杀戮信号.
问题是,根据文件 ......
kill信号节指定的信号被发送到主进程的进程组.(这样就可以杀死属于作业主进程的所有进程).默认情况下,此信号为SIGTERM.
这是令人担忧的,因为在我的子进程中,我通过proc_open()运行系统命令,它也生成新的子进程.因此,每当我运行时sudo stop audio-daemon,这个子进程(恰好是sox)会立即被终止,并且作业返回时会返回错误.显然,sox服从SIGTERM并按照它所说的去做......
最初,我想,"好吧.我只是改变kill signal发送一些本来就被忽略的东西,我只会在主流程中把它拿起来." 但根据手册,默认情况下只有两个信号被忽略:SIGCHLD和SIGURG(可能还有SIGWINCH).但我害怕得到假旗,因为这些也可以通过其他方式触发.
有一些方法可以使用手动调用"实时信号" 来创建自定义信号,但它也说明......
未处理的实时信号的默认操作是终止接收过程.
所以这没有帮助......
您是否可以想到任何方式可以让我的所有子流程在完成之前保持开放状态?我真的不想去挖掘sox的源代码来修改它的信号处理程序,虽然我可以设置SIGCHLD,SIGURG或SIGWINCH作为我的暴发终止信号并祈祷没有别的东西发送给我,我忍不住认为有更好的方法来做到这一点......任何想法?
感谢你的帮助!:)
我正在使用 SoX 将几种不同格式的音频文件转换为 mp3。根据docs,您可以使用-C参数来指定压缩选项,如比特率和质量,质量在小数点后,例如:
sox input.wav -C 128.01 output.mp3 (最高质量,较慢)
sox input.wav -C 128.99 output.mp3 (最低质量,更快)
我预计第二个听起来很糟糕,但是,两个声音之间的音频质量完全相同。如果是这种情况,我不明白为什么一个人的执行速度如此之慢,或者我不明白将压缩设置为更高的“质量”会得到什么。
有人可以告诉我使用高质量压缩与使用低质量压缩是否有真正的区别或优势?
PS我还检查了每个输出文件的文件大小,两者的大小完全相同。但是当散列时,每个文件都有不同的散列。