K
K
Kudrin Sergey2015-09-05 12:16:09
PHP
Kudrin Sergey, 2015-09-05 12:16:09

How to prevent simultaneous execution of a PHP script by cron?

Good afternoon, there was such a question and I just can not find a universal and simple solution. Can anyone help me understand the topic?
There is a php script that will be run by cron every minute. Since the script can be executed either in 5 seconds, or in half an hour, the task is this - if the last launch has not yet completed, then do not launch a new one so as not to interfere with each other and do one job.
The first thing that came to mind was to create a file at startup and delete it at the end of the work. Checking for its presence, the second copy will not start. The minus is obvious, if the script crashes for some reason and the file is not deleted, then the next cron will not start.
I remembered flock. I threw this option for verification:

$lockfile = fopen("my_script.lock", 'w');
if(flock($lockfile, LOCK_EX | LOCK_NB ) !== true)
  die("already running");
echo 'Good';
flush();
sleep(10);

I run the script through the browser the first time - it went to work, in the second tab I run it again and instead of the expected "already running" I see that the script has queued up and waits for the previous one to complete, after the completion of the 1st, it works out the 2nd .
I was looking for other implementation options on flock - the results are similar, the second run of the script leads to waiting for the completion of the first one.
This option does not suit me, because I don’t understand what will happen if the script is executed, for example, in 3 minutes, and it will be called by the cron every minute - will a long queue of people waiting be formed?
Prompt, please, any as much as possible universal decision.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
D
DevMan, 2015-09-05
@Kosha_not

$lock = fopen('/tmp/lock_file.lock', 'w');
if ( !($lock && flock($lock, LOCK_EX | LOCK_NB)) ) {
    exit( 'already running' );
}

M
maximw, 2015-09-05
@maximw

If the script already uses a Mysql connection, you can still use its semaphore implementation without "polluting" the file system.
Look at the function: GET_LOCK()
This method doesn't have the drawback you described. When the process that made the lock dies, the lock is released automatically.
P,S, If you are already using files, see register_shutdown_function() , where you can delete the lock file in an emergency.

E
entermix, 2015-09-05
@entermix

$fh = fopen(__FILE__, 'r');
        if (!flock($fh, LOCK_EX | LOCK_NB)) {
            die('Script is already running!');
        }

S
ShamblerR, 2015-09-08
@ShamblerR

lok is in the crown itself

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question