【发布时间】:2014-06-18 17:24:53
【问题描述】:
我想使用 PHP 中的 Web 界面分别读取和写入 C 应用程序的 STDOUT 和 STDIN。为此,我有一个测试 c 应用程序“hello.c”,它在特定睡眠后输出一个字符串,使用 PHP 我执行该 C 应用程序。我在 PHP 中使用流选择函数并检测该 C 应用程序的标准输出何时发生变化。我阅读了应用程序输出,但在 PHP 上,即使 C 应用程序输出已完成,我也会在 read discriptor 上更改状态。我的 c 应用程序、PHP 和浏览器输出代码如下所示;
hello.c
#include<stdio.h>
void main(void)
{
int i = 0;
for(i = 0; i < 5; i++)
{
printf("hello world\n");
sleep(1);
}
}
PHP
<?php
execute_prog('/var/www/html/test/./hello3');
function execute_prog($exe)
{
set_time_limit(1800);
$exe_command = escapeshellcmd($exe);
$descriptorspec = array(
0 => array("pipe", "r"), // stdin -> for execution
1 => array("pipe", "w"), // stdout -> for execution
2 => array("pipe", "w") // stderr
);
$process = proc_open($exe_command, $descriptorspec, $pipes);//creating child process
if (is_resource($process))
{
while(1)
{
$write = NULL;
$read = array($pipes[1]);
$err = NULL;
$except = NULL;
if (false === ($num_changed_streams = stream_select($read, $write, $except, 0)))
{
/* Error handling */
echo "Errors\n";
}
else if ($num_changed_streams > 0)
{
/* At least on one of the streams something interesting happened */
//echo "Data on ".$num_changed_streams." descriptor\n";
if($read)
{
echo "Data on child process STDOUT\n";
$s = fgets($pipes[1]);
print $s."</br>";
flush();
}
else if($write)
{
echo "Data on child process STDIN\n";
}
else if($err)
{
echo "Data on child process STDERR\n";
}
$num_changed_streams = 0;
}
}
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
echo "exitcode: ".proc_close($process)."\n";
}
return $ret;
}
?>
PS 命令的结果
ps -eaf | grep hello
apache 24157 22641 0 10:01 ? 00:00:00 [hello3] <defunct>
浏览器输出
Data on child process STDOUT hello world
Data on child process STDOUT hello world
Data on child process STDOUT hello world
Data on child process STDOUT hello world
Data on child process STDOUT hello world
Data on child process STDOUT
Data on child process STDOUT
Data on child process STDOUT
知道为什么我不断收到“关于子进程 STDOUT 的数据”吗?在持续显示此文本时,“ps”结果仍如上所示。
请指导。
编辑 我添加了一个调整,当 fgets 的结果为空时,我打破了 while 循环
$s = fgets($pipes[1]);
if(empty($s))
{
echo "Empty";
break;
}
现在不显示连续的“关于子进程 STDOUT 的数据”。正如我所说的那样,即使 C 应用程序停止发送数据,我仍然不知道为什么读取描述符会变为真。有人请
【问题讨论】:
标签: php c linux stdout multitasking