You are here: Home Development PHP PHP CLI: Simple Process Control in Linux with PCNTL_EXEC
PHP CLI: Simple Process Control in Linux with PCNTL_EXEC PDF Print E-mail
User Rating: / 1
PoorBest 
Development - PHP
Written by Rick   
Friday, 15 May 2009 00:00

I've been working on a project using php executed from the command line. The project downloads files via FTP from several sources, renames the files and tosses the files into a new directory structure. I never thought I'd find a legitmate reason to create a "file scrounger".

Throughout development I've been executing the script from the command line to test and debug. Happily building the app step by step. Once it was complete I thought I'd just be able to execute it from a cron job on my Linux box and be done with it. Boy, was I wrong!!!

Unbeknownst to me, php run from the command line in a Linux environment from cron spawns processes like salmon produce eggs. It bogged-down the machine causing problems as you might imagine. The obvious question arose, "How do I stop that?". Process Control, of course. I can say, "of course" now because I've been "down that road". My first thought was OMG. I wondered how many more lines of code I needed to accomplish the task.

After days of research and testing it came down to a very simple script using PCNTL_EXEC that calls a class. The file I was trying to execute is named retrieve.php (yeah, I know not very original). To run the app in a single process, I created another file name start.php. Inside start.php, not including comments, there are 13 lines of code. It looks like this;

 

#!/usr/bin/php
<?php
include "class_pid.php";

$pid = new pid('/tmp');
if($pid->already_running) {
//echo "Already running.\n";
exit;
}
else {
pcntl_exec('/home/rbma/retrieval/retrieve.php');
}

?>

The class;

 

<?php
class pid {

protected $filename;
public $already_running = false;

function __construct($directory) {

$this->filename = $directory . '/' . basename($_SERVER['PHP_SELF']) . '.pid';

if(is_writable($this->filename) || is_writable($directory)) {

if(file_exists($this->filename)) {
$pid = (int)trim(file_get_contents($this->filename));
if(posix_kill($pid, 0)) {
$this->already_running = true;
}
}

}
else {
die("Cannot write to pid file '$this->filename'. Program execution halted.\n");
}

if(!$this->already_running) {
$pid = getmypid();
file_put_contents($this->filename, $pid);
}

}

public function __destruct() {

if(!$this->already_running && file_exists($this->filename) && is_writeable($this->filename)) {
unlink($this->filename);
}

}

}
?>

 

That's it!. The program runs with 2 processes. 1 shell plus retrieve.php in it's own process. Now I can sleep at night!!!

 

Write comment
Your Contact Details:
 
Comment:
[b] [i] [u] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch:
:(:shock::X:side::):P:unsure::woohoo::huh::whistle:;):s
:!::?::idea::arrow:
Security Please input the anti-spam code that you can read in the image.