多亏了谷歌,我才来到这里,并决定这篇已有十年历史的帖子需要更多信息,基于如何在 PHP 中调用/启动进程并使用进程 ID 杀死它......
想象一下,你想执行一个命令(这个例子使用 ffmpeg 将 windows 系统上的文件流式传输到 rtmp 服务器)。你可以命令这样的事情:
ffmpeg -re -i D:\wicked_video.mkv -c:v libx264 -preset veryfast -b:v 200k -maxrate 400k -bufsize 6000k -pix_fmt yuv420p -g 50 -c:a aac -b:a 160k -ac 2 -ar 44100 -f flv rtmp://<IP_OF_RMTP_SERVER>/superawesomestreamkey > d:\demo.txt 2> d:\demoerr.txt
第一部分在这里解释,该命令的最后一部分输出到具有该名称的文件以用于记录目的:
> d:\demo.txt 2> d:\demoerr.txt
因此,让我们假设该命令有效。你测试了它。要使用 php 运行该命令,您可以使用 exec 执行它,但这需要时间(另一个主题,检查set_time_limit),它是 ffmpeg 通过 php 处理的视频。不是要走的路,但在这种情况下正在发生。
您可以在后台运行该命令,但该进程的 pid 是什么?我们出于某种原因想要杀死它,psexec 只给出一个用户运行的“进程 ID”。在这种情况下只有一个用户。我们希望同一个用户有多个进程。
这是一个在 php 中获取已运行进程的 pid 的示例:
// the command could be anything:
// $cmd = 'whoami';
// This is a f* one, The point is: exec is nasty.
// $cmd = 'shutdown -r -t 0'; //
// but this is the ffmpeg example that outputs seperate files for sake
$cmd = 'ffmpeg -re -i D:\wicked_video.mkv -c:v libx264 -preset veryfast -b:v 200k -maxrate 400k -bufsize 6000k -pix_fmt yuv420p -g 50 -c:a aac -b:a 160k -ac 2 -ar 44100 -f flv rtmp://10.237.1.8/show/streamkey1 > d:\demo.txt 2> d:\demoerr.txt';
// we assume the os is windows, pipe read and write
$descriptorspec = [
0 => ["pipe", "r"],
1 => ["pipe", "w"],
];
// start task in background, when its a recource, you can get Parent process id
if ( $prog = is_resource( proc_open("start /b " . $cmd, $descriptorspec, $pipes ) ) )
{
// Get Parent process Id
$ppid = proc_get_status($prog);
// this is the 'child' pid
$pid = $ppid['pid'];
// use wmic to get the PID
$output = array_filter( explode(" ", shell_exec("wmic process get parentprocessid,processid | find \"$pid\"" ) ) );
array_pop($output);
// if pid exitst this will not be empty
$pid = end($output);
// outputs the PID of the process
echo $pid;
}
上面的代码应该回显“inBackground”运行进程的 pid。
请注意,如果 pid 仍在运行,您需要保存 pid 以便稍后将其杀死。
现在你可以这样做来杀死进程:(想象 pid 是 1234)
//'F' to Force kill a process
exec("taskkill /pid 1234 /F");
这是我在stackoverflow上的第一篇文章,我希望这会对某人有所帮助。度过一个美好而不孤单的圣诞节♪♪