gpt4 book ai didi

php - 由 PHP 执行的 C 应用程序在执行完成之前不会在浏览器上显示输出

转载 作者:太空宇宙 更新时间:2023-11-04 05:26:42 25 4
gpt4 key购买 nike

我正在通过 PHP 中的 Web 界面执行 C 应用程序。 C 应用程序的输出在其完全执行后显示在浏览器上。我希望一旦 C 应用程序“printf”函数打印输出,它就应该显示在浏览器上。

我尝试在 PHP 中使用 flush、ob_flush、ob_flush_end 设置 header ,但没有用。然后在我的 C 应用程序中添加 fflush(stdout),它会立即更新浏览器上的输出。

问题是我不想在 C 应用程序中添加任何东西我想在 PHP 中实现它。我的 C 代码和 PHP 脚本在下面给出

你好.c

#include<stdio.h>

void main(void)
{
int i = 0;

for(i = 0; i < 5; i++)
{
printf("hello world\n");
//fflush(stdout);//it immediately updates the browser output if uncommented
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>";

ob_flush();
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;
}

?>

如有任何帮助,我们将不胜感激。

最佳答案

这与 stdio 流缓冲有关。当您在终端上运行 hello3 时,您只会立即观察到结果,因为 stdout 连接到终端,并且在终端中默认情况下是行缓冲的。

stdio 库非常聪明,可以检测到在管道上运行时没有终端连接到 stdout 并将其变为完全缓冲(出于性能原因)。这就是添加 fflush(stdout); 立即更新浏览器的原因。

如果您希望您的浏览器立即接收结果,那么fflush(stdout); 每次当您想要更新或将缓冲更改为行缓冲或无缓冲时。

setvbuf(stdout, NULL, _IONBF, 0); // no buffering
setvbuf(stdout, NULL, _IOLBF, 0); // line buffered
setvbuf(stdout, NULL, _IOFBF, 0); // fully buffered

编辑:

如果您无法修改 C 可执行文件,那么您可以注入(inject)一个库来为您设置此选项。这是一个最小的例子:

// unbuf.c
#include <stdio.h>

void _nobuff_initialiser(void) {
setvbuf(stdout, NULL, _IONBF, 0); // no buffering
}

编译

cc -o unbuf.so -fPIC -shared -init __nobuff_initialiser unbuf.c      # Linux
cc -o unbuf.dylib -dynamiclib -init __nobuff_initialiser unbuf.c # OS X

设置环境变量运行

LD_PRELOAD=<pathto unbuf.so> ./hello3                      # Linux
DYLD_INSERT_LIBRARIES=<path to unbuf.dylib> ./hello3 # OS X

或来自 PHP:

putenv("LD_PRELOAD=<pathto unbuf.so>");                    # Linux
putenv("DYLD_INSERT_LIBRARIES=<path to unbuf.dylib>"); # OS X

关于php - 由 PHP 执行的 C 应用程序在执行完成之前不会在浏览器上显示输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23425676/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com