• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3210
  • Last Modified:

Find running process id using php within crontab (RHEL4)

I'm writing a php file that -via crontab- gets executed once every minute to send out mails. I'm not being able to device a method to prevent multiple instances of this program from running simultaneously. I only want ONE instance at a time.

My logic is:
1) Get all running processes using "ps auxwww" (plus some awk magic to get only pids for the specified file)
2) If there is more than one process running, meaning there is me, plus another process, exit gracefully.

The problem is that when I run this (see the code window below), I can ONLY see the process id of the currently running php file and none other. Even without filtering anything out, the output of ps auxw only has one process!

I'm guessing there is some sort of user permission thing going on. How can I go around this?

Thanks!

Context: Dedicated server running Red Hat Enterprise Linux 4 with PHP 5.2.9. I have root shell access.
<?php
// over simplified version
echo exec("ps auxw");
?>

Open in new window

0
poisa
Asked:
poisa
  • 4
  • 2
  • 2
  • +1
1 Solution
 
EMB01Commented:
Does your PHP script check a database?

What I do is add a field to whatever table gets checked by the script for a "processed_on". Then, in the first iteration, simply update the field with 00/00/00. Your script should only check for rows in the table that have a NULL value for the "processed_on" date. Then, when the iteration is complete, update the field again and fill it with the appropriate date like 04/20/09.

Please let me know if you have any questions.
0
 
poisaAuthor Commented:
EMB01, thanks for your answer, but my problem hasn't got to do with keeping track of what rows to deal with.

What I need is a way to prevent multiple instances of the program from running.

0
 
EMB01Commented:
Sorry, I only know of the alternative I posted above. If you don't mind my asking, what's the problem if the script only runs a few lines before being told to continue or exit.

Here's a shell_exec class I found:
http://us.php.net/manual/en/function.shell-exec.php#59898

It's also been attached.

Sorry I can't help much more.
<?php
/**
 * @author     Ashraf M Kaabi
 * @name       Advance Linux Exec
 */
class exec {
    /**
     * Run Application in background
     *
     * @param     unknown_type $Command
     * @param     unknown_type $Priority
     * @return     PID
     */
    function background($Command, $Priority = 0){
       if($Priority)
           $PID = shell_exec("nohup nice -n $Priority $Command > /dev/null & echo $!");
       else
           $PID = shell_exec("nohup $Command > /dev/null & echo $!");
       return($PID);
   }
   /**
    * Check if the Application running !
    *
    * @param     unknown_type $PID
    * @return     boolen
    */
   function is_running($PID){
       exec("ps $PID", $ProcessState);
       return(count($ProcessState) >= 2);
   }
   /**
    * Kill Application PID
    *
    * @param  unknown_type $PID
    * @return boolen
    */
   function kill($PID){
       if(exec::is_running($PID)){
           exec("kill -KILL $PID");
           return true;
       }else return false;
   }
};
?> 

Open in new window

0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
tkalchevCommented:
Assuming your script is called mailerscript.php

crontab :

* * * * * [ -z "$(ps ax|grep mailerscript.php|grep -v grep)" ] && mailerscript.php
0
 
poisaAuthor Commented:
EMB01: "If you don't mind my asking, what's the problem if the script only runs a few lines before being told to continue or exit."

There's no problem at all with that. The real problem is that in my environment, the class you suggest will never work as it relies on exec("ps $PID", $ProcessState) to know whether a process is running or not.
As mentioned in my initial post, executing that command will return ONLY the currently running process and NOTHING else.

tkalchev, I still need to try your option out. Could you explain a little bit what it does? I'm not very proficient  in shell scripts and I'm not sure what the -z, the brackets, the && and the "$" do.
0
 
tkalchevCommented:
ps ax - gives a list of all running processes
grep mailerscript.php - displays only the lines, which contain "mailerscript.php"
grep -v grep - filters the word "grep" out

$(xxx) - executes a command and returns its output, same as `xxx`, but at least for me looks much clear

-z  - tests if the following string is empty
&& - executes the following command is the result of the previous one is zero ( http://www.gnu.org/software/bash/manual/bashref.html#Lists ). Same as
if [ -z "$(ps ax|grep mailerscript.php|grep -v grep)" ]; then
  malerscript.php
fi ,but much more compact :)

So the meaning of the expression is the following :
Give me the list of all running processes, containing "mailerscript.php" and not containing "grep" and if this list is empty, execute mailerscript.php
0
 
poisaAuthor Commented:
I ended up tweaking this a little but your suggestion did work. Thanks!
0
 
mriz81Commented:
This is the function that tell is a process is running or not.
function processExists($process)
 {
		// Check if file is in process list
		exec("ps -ef|grep $process|grep -v grep", $pids);
		if (count($pids) >= 1)
		{
			$pids[0] = implode(" ", array_filter(explode(" ", $pids[0])));			
			$data = explode(" ", $pids[0]);
			if( isset($data[1]) )
			{
				echo($file . " executing with pid " . $data[1]);
				exit();
			}
		}
		echo($file . " not executing.");
}

Open in new window

0
 
poisaAuthor Commented:
mriz81,

Your function relies on exec() too. Won't work for my setup.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 4
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now