How to get a list of PHP processes running on a server with PHP

I have a cronjob that runs a PHP file that runs DAEMON written in PHP, but I only want to run DAEMON, if there are no other instances of it, how can I get a list of PHP processes running in order to find if my DAEMON is working . I was thinking of some kind of exec that will generate a list that I can store in an array. Any ideas? thanks

+4
source share
2 answers

For a list of PHP processes, check out this question:

How to get a list of running php scripts using PHP exec ()?

Another option is that you can get a file lock and then check it before running: for example:

$thisfilepath = $_SERVER['SCRIPT_FILENAME']; $thisfilepath = fopen($thisfilepath,'r'); if (!flock($thisfilepath,LOCK_EX | LOCK_NB)) { customlogfunctionandemail("File is Locked"); exit(); } elseif(flock($thisfilepath,LOCK_EX | LOCK_NB)) // Acquire Lock { // Write your code // Unlock before finish flock($thisfilepath,LOCK_UN); // Unlock the file and Exit customlogfunctionandemail("Process completed. File is unlocked"); exit(); } 

Basically, in the example above, you first check if the file is locked or not, and if it is not locked (which means the process is completed), you can get the lock and start your code.

thanks

+3
source

Here is my complete solution to take control of cron with a php script that envolves mysql db for configuration and logging. You should find the answers to your questions in the source code.

Cron_Job Class:

 class Cron_Job { /** * check if job is still running * @param int $pid * @return boolean */ public function isJobRunning($pid) { try { $result = shell_exec(sprintf("ps %d", $pid)); if (count(preg_split("/\n/", $result)) > 2) { return true; } } catch (Exception $e) { } return false; } /** * deletes job from run stack * @param int $pid */ public function deleteRunningJob($pid) { $sql = "delete from croner_running_pids where pid = '$pid'"; $ret = framework_Database::getInstance("****")->delete($sql); } /** * adds job into run stack * @param int $pid */ public function addRunningJob($pid, $outputfile) { $sql = "insert into croner_running_pids (pid, `outfile`) values ('$pid', '$outputfile')"; $id = framework_Database::getInstance("****")->insert_db($sql); } } 

class Cron_Log:

 class Cron_Log { public static function setRunLog($jobid, $message) { $date = date("Ymd H:i:s"); $sql = "insert into croner_run_log (jobid, cas, message) values ('$jobid', '$date', '$message')"; framework_Database::getInstance("****")->insert($sql); } /** * sets first run of job log * @param int $jobid * @param int $pid * * @return $id */ public static function setJobLogStart($jobid, $pid) { $start = date("Ymd H:i:s"); $sql = "insert into croner_log (job_id, start_run, pid) values ('$jobid', '$start', '$pid')"; $id = framework_Database::getInstance("****")->insert_db($sql); return $id; } /** * finalize log for specified run * @param int $logid */ public static function setJobLogEnd($pid, $endRunTime, $message) { $endRunTime = date("Ymd H:i:s", $endRunTime); $message = mysql_real_escape_string($message); $sql = "update croner_log set end_run = '$endRunTime', output = '$message' where pid = '$pid' and end_run is null"; framework_Database::getInstance("****")->update($sql); } } 

Script execution:

 $sql = "select id, runtime, execute_path from croner where runtime is not null and execute_path is not null"; //I am using database wrapper $ret = framework_Database::getInstance("****")->select($sql); $cj = new Cron_Job(); //echo date('dmYNW H:i:s'); echo "<br>"; if(count($ret['id']) > 0) { foreach($ret['id'] as $key=>$id) { $runtime = $ret['runtime'][$key]; if(empty($runtime)) continue; $cmd = $ret['execute_path'][$key]; $outputfile = "/var/www-intranet/croner/outputs/" . $id . "_" . time(); //echo $runtime; //if pregmatch than get details if(preg_match($runtime, date('dmYNW H:i'), $matches)) { Cron_Log::setRunLog($id, "Starting job $cmd"); $cmd = sprintf("%s > %s 2>&1 & echo $!", $cmd, $outputfile); exec($cmd, $pid); $pid = $pid[0]; //add log that job has started $cj->addRunningJob($pid, $outputfile); Cron_Log::setJobLogStart($id, $pid); usleep(2000); } else { continue; } } } sleep(1); //check running pids $sql = "SELECT * FROM croner_running_pids"; $ret = framework_Database::getInstance("****")->select($sql); //print_r($ret); if(isset($ret['pid']) && count($ret['pid'])) { foreach($ret['pid'] as $key=>$pid) { if(is_numeric($pid) && !$cj->isJobRunning($pid) && file_exists($ret['outfile'][$key])) { //delete pid from run table $cj->deleteRunningJob($pid); $outfile = $ret['outfile'][$key]; $endRunTime = filemtime($outfile); //echo $endRunTime; $message = file_get_contents($outfile); Cron_Log::setJobLogEnd($pid, $endRunTime, $message); @unlink($outfile); } } } 

DB Tables:

Croner table:

 Field Type Null Key Default Extra id int(11) NO PRI NULL auto_increment jobname varchar(250) NO NULL descr text NO NULL runtime varchar(150) NO NULL execute_path text NO NULL creator int(11) NO NULL last_run_time timestamp NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP 

Croner_log table:

 Field Type Null Key Default Extra id int(11) NO PRI NULL auto_increment job_id int(11) NO NULL start_run timestamp YES NULL end_run timestamp YES NULL pid int(11) NO NULL output longtext NO NULL 

Croner_run_log table:

 Field Type Null Key Default Extra id int(11) NO PRI NULL auto_increment jobid int(11) NO NULL cas timestamp NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP message varchar(255) NO NULL 

Croner_running_pids table:

 Field Type Null Key Default Extra id int(11) NO PRI NULL auto_increment pid int(11) NO NULL pidfile varchar(250) NO NULL outfile varchar(250) NO NULL 

The idea is to have the configuration in the database, where I saved the templates for preg_match in a specific format (date ('dmYNW H: i: s')). This script runs every minute.

Then I always select all the templates and compare them with the results from the date function.

If a match is found, I launched the command saved for this task - put it in the background and save its pid in the database - a separate table that stores all the output from the tasks.

In the end, I check the database for jobs that are marked as running and looking for whether they are in the process list.

0
source

Source: https://habr.com/ru/post/1488420/


All Articles