Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP proc_open opens multiple times

I have a utility function used for executing a program through CLI (cmd, bash etc). It returns an array of 3 items: STDOUT, STDERR and EXIT CODE.

So far, it's been working nicely without issues. In fact, the problem I have with it doesn't really hinder it's functionality, but I'm concerned about performance.

The problem is that in certain cases, PHP runs the same command multiple times (3 times in my case), even if it was supposed to only do this once.

/**
 * Executes a program and waits for it to finish, taking pipes into account.
 * @param string $cmd Command line to execute, including any arguments.
 * @param string $input Data for standard input.
 * @param boolean $log Whether to log execution failures or not (defaults to true).
 * @return array Array of "stdout", "stderr" and "return".
 */
public static function execute($cmd,$stdin=null,$log=true){
    //static $once=true; if(!$once)die; $once=false;
    $proc=proc_open($cmd, array(
        0=>array('pipe','r'),
        1=>array('pipe','w'),
        2=>array('pipe','w')   ), $pipes);
    fwrite($pipes[0],$stdin);                fclose($pipes[0]);
    $stdout=stream_get_contents($pipes[1]);  fclose($pipes[1]);
    $stderr=stream_get_contents($pipes[2]);  fclose($pipes[2]);
    $return=proc_close($proc);
    if($return!=0 && $log)
        xlog('Error: Program execution returned failure.',$stdout,$stderr,$return);
    return array( 'stdout'=>$stdout, 'stderr'=>$stderr, 'return'=>$return );
}

Note the commented line (line 9). That was for testing. I enabled it to ensure the target program only runs once (I was thinking my code may be calling the same function somehow). But even with that line enabled, the program still ran multiple times.

As it is, I have 2 places in my code where I'm executing the same program (on different occasions). The command line is the same for both of them.

However, on one occasion, the program runs once, while in the occasion, PHP runs the program 3 times.

I've been monitoring and seeing this behavior under Process Explorer. I'm using Windows 7 x64. The program is 32 bit, as is PHP.

Edit: The program in question is custom developed, and it doesn't open new processes.

like image 793
Christian Avatar asked Jan 23 '11 20:01

Christian


1 Answers

Your code to test that it is run only once looks flawed.

If you have 2 php processes running they will not share a static variable. So it could be possible you have having simultaneous requests causing this to run more than once.

Second, you should be setting $once to false at the end of the function, otherwise the die will never be reached.

Try adding some logging to see if the function is being called from twice.

Create some unit/stress tests that just run the external application. If you see multiple processes, then there is something with your app that is wrong, not the php code.

like image 145
Byron Whitlock Avatar answered Nov 15 '22 04:11

Byron Whitlock