php proc open 返回,如何等待php中proc_open()执行的进程?

标签:php

请阅读此问题后,不要说它已被复制.我已经在网上搜索过,但是没有一种解决方案适合我.

我在做什么:->

我正在通过在本地主机上运行apache服务器通过php获取源文件(例如.c).我将该文件保存在“ / code /”目录中,并在php中使用proc_open()编译并执行此源文件.现在我想要等待主要的php脚本,直到“ proc_open()”创建的进程终止,所以我使用了“ pcntl_waitpid()”.但是我认为使用“ pcntl_waitpid()”存在问题,因为“ pcntl_waitpid()”之后的脚本没有执行.

由“ pcntl_waitpid()”创建的进程从“ /code/input.txt”文件获取输入,并将输出提供给“ /code/output.txt”文件,因此出于重定向目的,我使用proc_open(),这样我可以轻松地重定向流.

我的机器配置:

操作系统-> Ubuntu 12.04 LTs

PHP 5.3.10

APACHE 2.2.22

在本地主机上运行

权限:-

/ code-> 777

主php文件所在的文件夹-> 777(由于安全原因,我知道777不好,但是由于我在本地服务器上运行脚本,因此这些权限没有问题.)

我想要的是 :-

谁能告诉我任何方式,以便我可以停止主要的php脚本,直到proc-open()创建的进程终止,或者有人可以告诉我其他方式来满足我的重定向要求?

这是代码的一部分:

$descriptors = array(

2 => array("pipe","w")

);

$process = proc_open($cmd,$descriptors,$pipes,$code);

sleep(2);

if(is_resource($process))

{

$status = proc_get_status($process);

$pid = $status ["pid"];

echo getmypid()."
";

echo $pid;

if(pcntl_waitpid($pid,$child_status) == -1)

{

fclose($pipes[2]);

proc_close($process);

exit("Sorry!Unable to compile the source_file.\n");

}

while(!file_exists("/code/test"))

{

proc_close($process);

echo stream_get_contents($pipes[2]),"\n";

fclose($pipes[2]);

exit("Sorry!Unable to compile the source_file.\n");

}

echo "Compiled Successfully!\n";

echo "Running test cases...\n";

fclose($pipes[2]);

proc_close($process);

}

else

{

exit("Sorry!Unable to compile the source_file.\n");

}

谢谢!

解决方法:

最好使用管道解决此问题. pcntl_wait()仅是Linux,除非您处理fork(),否则它不是很有用(以我的经验).使用stream_select等待.如果需要,我将进一步研究我的旧脚本,但这类似于:

$cwd = "/code/";

chmod("/code/test.c",0777);

switch($xtension)

{

case "c":

$cmd = "gcc -g test.c -o test -lm ";

break;

case "cpp":

$cmd = "g++ -g test.cpp -o test";

break;

case "java":

$cmd = "javac test.java";

break;

}

$descriptors = array( 0 => array('pipe', 'r'), // stdin

1 => array('pipe', 'w'), // stdout

2 => array('pipe', 'a') // stderr

);

$process = proc_open($cmd,$descriptors,$pipes,$code);

stream_set_blocking($pipes[2], 0);

if(($error = stream_get_contents($pipes[2]) !== false)

{

// error starting command (error *in* command)

die($error);

}else

{

stream_set_blocking($pipes[2], 1);

/* Prepare the read array */

$read = array($pipes[1], $pipes[2]);

$write = NULL;

$except = NULL;

$tv_sec = 0; // secs

$tv_usec = 1000; // millionths of secs

if(false === ($rv = stream_select($read, $write, $except, $tv_sec, $tv_usec)))

{

die('error in stream_select');

}else if ($rv > 0)

{

foreach($read as $pipe_resource)

{

if($pipe_resource == $pipes[1])

{

// is stdout

}else if($pipe_resource == $pipes[2])

{

// is stderr

}

}

}else

{

// select timed out. plenty of stuff can be done here

}

}

// this will be executed after the process terminates

您可以使用多种方法来解决问题.

首先,您可以将select中的超时设置为零,它将无限期地等待.如果您的可执行文件不使用stdout,则在进程终止时stream_select函数将阻塞,直到关闭管道为止.

如果您的进程确实使用stdout和stderr,则可以在循环中使用select并在每次select返回时检查管道是否关闭.如果将来将来需要的话,这也将使您能够有效地处理来自stdout和stderr的信息(json非常有用).

标签:php

来源: https://codeday.me/bug/20191122/2057839.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值