3

I have a cron job that executes every minutes. But I discovered thats it's running multiple times. I'm looking for a way to check if the process is still running then don't start a new one, or terminate the already running process before starting a new one.

Daniel Kmak
  • 18,164
  • 7
  • 66
  • 89
Toni
  • 670
  • 11
  • 29

4 Answers4

5

If you want the php solution, the simple way is to create a lock file, each time script is executed , check if file exist then exit script, if not let script go to end. But i think it's better to use flock in cron instruction ;)

<?php
    $filename = "myscript.lock";
    $lifelimit = 120; // in Second lifetime to prevent errors
    /* check lifetime of file if exist */
    if(file_exists($filename)){
       $lifetime = time() - filemtime($filename);
    }else{
       $lifetime = 0;
    }
    /* check if file exist or if file is too old */
    if(!file_exists($filename) ||  $lifetime > $lifelimit){
        if($lifetime > $lifelimit){
            unlink($filename); //Suppress if exist and too old
        }
        $file=fopen($filename, "w+"); // Create lockfile
        if($file == false){
            die("file didn't create, check permissions");
        }
        /* Your process */
        unlink($filename); //Suppress lock file after your process 
    }else{
        exit(); // Process already in progress
    }
Fky
  • 2,133
  • 1
  • 15
  • 23
  • Thanks. this gave me what I wanted. though I had to increase the $lifelimit , because my script might take longer time time to complete at once. – Toni Sep 08 '15 at 17:17
  • Great ! :) Yeah you can customize to get what exactly you want =) – Fky Sep 09 '15 at 07:30
4

Here can be lot of variants to test it. For example you can update DB when task is in progress and each run test this flag. Or you can open file and lock it. And when your script executed - test if you can lock this file. Or you can read process list and if there no your script - continue execution

So, main goal is - create somewhere flag, that will tell your script that it is already in progress. But what is better for your specific case - it is your choice.

UPDATE After some researches found good variant to use system "flock" command to do same things. Might be useful:

* * * * * flock -n /some/lockfile command_to_run_every_minute
Vladimir Gilevich
  • 861
  • 1
  • 10
  • 17
1

As of all the locking mechanisms (including flock and lock files) - please note that if something will go wrong, your cron job will never run automatically:

  • flock: if server crashes (and this happens sometimes) you'll have an everlasting lock (until manually removed) on the command.
  • lock file: if command fails with fatal error, your file won't be removed, so the cron job won't be able to start (sure, you can use error handlers, this anyways won't save you from failures due to memory limits or server reset).

So, I recon running system "ps aux" is the best solution. Sure, this works only on Linux-based systems (and MacOS).

1

This snipped could be good solution for the problem. Please note that "grep -v grep" is necessary to filter out the particular query in a shell_exec.

#!/usr/bin/php -f
<?php

$result = shell_exec("ps aux | grep -v grep |  grep ". basename(__FILE__) );
echo strlen($result) ? "running" : "not running";

This code is handy when you need to define if this particular file run by cron job

volkinc
  • 2,143
  • 1
  • 15
  • 19