【问题标题】:php background process PID problemphp后台进程PID问题
【发布时间】:2010-11-05 16:32:58
【问题描述】:

我有这个脚本,如果我运行它,我会在数据库中输入一个与顶部命令列出的不同的 PID 号:

<?php
error_reporting(0);

include_once "config/mysql.php";

// the path
$path = "PATH=$PATH:/share/MD0_DATA/.qpkg/Optware/bin:";

//random number for the log file name
$random = rand(1,500000);

//initial download location
$init_loc="/share/MD0_DATA/Qdownload/plowshare";

$items = rtrim($_POST['items'],",");
$sql = mysql_query("SELECT url, pid FROM plow WHERE id IN ($items)") or die ('Error: ' . mysql_error());

while ($db_row = mysql_fetch_assoc($sql)) { 
  //random number for the log file name
  $random = rand(1,500000);
  //log file name
  $out_file = '/share/MD0_DATA/Qdownload/plowshare/Logs/log'.$random.'.txt';
  //command 1
  $command = exec("($path" . " nohup /opt/bin/plowdown -o '$init_loc' " . "'".$db_row['url']."' 2> " . "'$out_file' > /dev/null &);" . "echo $$;", $out); 
  exec($command, $out);
  $query = mysql_query("UPDATE plow SET state = 'Active', pid = '$out[0]' WHERE id IN ($items)") or die ('Error: ' . mysql_error());
 }
mysql_close();

?>

结果总是一样的:

在数据库中输入的PID号:11159(随机数,现在选择只是为了说明一点)

顶部命令列出的PID号:11161。

顶部命令列出的 PID 号总是比数据库中的 PID 号大 2。

它让我发疯......

谢谢,

克里斯蒂安。

【问题讨论】:

  • top(或ps aux)中的11159 是什么?有没有可能是nohup
  • 再次运行函数,我得到了这个结果: 7696 httpdusr 1856 S /opt/bin/bash /opt/bin/plowdown using top,在数据库中输入了 7694 ... ???
  • 但是7694 是什么?我的猜测是您返回的 PID 是 nohup 的 pid。但是nohup 在它自己的 tty 上将命令作为一个新进程跨越,所以 pid 应该不同于 nohup 的...
  • @ircmaxell 如果您可以访问 Linux 机器,请尝试运行此命令 nohup "some command" 2> output.txt > /dev/null & ,最后看到的数字应该是nohup 的 PID 号并使用 top 命令检查该命令的 PID 号。谢谢。

标签: php exec


【解决方案1】:

$$ 返回运行命令的脚本的 PID,不是最后执行命令的 PID。例如,在 bash shell 中回显 $$ 通常会返回 bash 本身的 PID。从脚本中回显 $$ 会返回脚本的 PID。

所以,你得到+2差异的原因是:

  • exec() 生成一个 PID 为 1 的“shell”
  • nohup 使用 PID 2 执行
  • /usr/bin/plowdown 使用 PID 3 执行
  • echo $$ 返回shell的PID,即1

【讨论】:

  • 但是如果我应用相同的逻辑并通过 Putty 运行命令,我应该得到 nohup 的 PID,而 plowdown 的 PID 应该是 nohup_PID+1。但是如果我运行该列表中的顶部命令,我可以看到 plowdown 的 PID 与我刚刚运行的命令输出的 PID 相同。非常有趣……谢谢。
  • 我在没有 nohup 的情况下运行 $command 并且发生了同样的事情,存储在数据库中的 PID 与顶部列出的 PID 之间存在 +2 差异。 ??!
【解决方案2】:

就像 netcoder 说的,你不能用 $$,而是用 $!它返回最后一个后台进程的 pid。试试这样的

$command = exec("($path" . " nohup /opt/bin/plowdown -o '$init_loc' " . "'".$db_row['url']."' 2> " . "'$out_file' > /dev/null ) & " . 'echo ${!};', $out); 

注意&amp;在括号外,后面没有分号。

【讨论】:

  • 如果我尝试你的代码,同样的事情,差异仍然存在。我需要看看我是否在另一台机器上尝试使用相同的规则,如果这被证明是“常量”,我可以将值添加 2 并将其输入到数据库中。谢谢。
猜你喜欢
  • 2013-01-11
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
  • 1970-01-01
相关资源
最近更新 更多