我一直用:
$pid = exec("/usr/local/bin/php file.php $args > /dev/null & echo \$!");
但我正在使用XP虚拟机来开发一个Web应用程序,我不知道如何在Windows中获取pid。
我在cmd上尝试了这个:
C:\\wamp\\bin\\php\\php5.2.9-2\\php.exe "file.php args" > NUL & echo $!
它会执行文件,但输出为“$!”
如何将pid放入var $ pid? (使用php)
答案 0 :(得分:9)
我正在使用Pstools,它允许您在后台创建一个进程并捕获它的pid:
// use psexec to start in background, pipe stderr to stdout to capture pid
exec("psexec -d $command 2>&1", $output);
// capture pid on the 6th line
preg_match('/ID (\d+)/', $output[5], $matches);
$pid = $matches[1];
有点hacky,但它完成了工作
答案 1 :(得分:1)
多亏了谷歌,我才来到这里,并根据 How to invoke/start a Process in PHP and kill it using Process 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
第一部分解释了 here,该命令的最后一部分输出到具有该名称的文件以用于记录目的:
> 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 是 1234)
//'F' to Force kill a process
exec("taskkill /pid 1234 /F");
这是我在 stackoverflow 上的第一篇文章, 我希望这会帮助某人。度过一个美好而不寂寞的圣诞节♪♪
答案 2 :(得分:0)
您必须安装extra extension,但找到位于Uniformserver's Wiki的解决方案。
<强>更新强>
经过一些搜索后,您可能会同时查看tasklist
,您可以使用PHP exec
命令来获取您所追求的内容。
答案 3 :(得分:0)
这是SeanDowney回答的“骇人听闻”版本。
PsExec返回生成的进程的PID作为其整数退出代码。因此,您所需要做的就是这个:
<?php
function spawn($script)
{
@exec('psexec -accepteula -d php.exe ' . $script . ' 2>&1', $output, $pid);
return $pid;
} // spawn
echo spawn('phpinfo.php');
?>
仅在第一次运行PsExec时才需要-accepteula参数,但是,如果要分发程序,则每个用户都将第一次运行它,并且对于每个人来说都保留它不会有任何损害随后执行。
PSTools是一种快速简便的安装程序(只需将PSTools解压缩到某个位置并将其文件夹添加到您的路径中),因此没有充分的理由不使用此方法。