Linux's crontab command, which can be performed on a regular basis, and the minimum cycle is executed once per minute. About Crontab implementation per second can refer to my previous article "Linux Crontab implementation per second"
Now there is a problem, if the task is set to execute every minute, but it is possible that the task does not finish in a minute, then the system will perform the task again. Causes two identical tasks to execute.
For example:
?
test.php for
($i =0 $i <300; $i + +) {
echo date (' y-m-d h:i:s '). " \ r \ n ";
Sleep (1);
}
? >
Cycle 300 times, sleep 1 seconds per cycle. Execution takes 300 seconds or 5 minutes.
Set Crontab to execute per minute
* * * * * * php/home/fdipzone/php/test.php >>/home/fdipzone/php/test.log
2 minutes later, using the PS aux|grep test.php view, you can see that there are two test.php processes executing.
After 3 minutes, you see that there are 3 test.php processes executing.
fdipzone@ubuntu:/tmp$ PS aux|grep test.php
fdipzone 2995 0.0 0.0 4220 ? Ss 00:28 0:00/bin/sh-c php/home/fdipzone/php/test.php >>/home/fdipzone/php/test.log
fdipzone 2996 0.0 0.8 108328 8564? S 00:28 0:00 php/home/fdipzone/php/test.php
fdipzone 3033 0.0 0.0 4220 584? Ss 00:29 0:00/bin/sh-c php/home/fdipzone/php/test.php >>/home/fdipzone/php/test.log
Fdipzone 3034 0.1 0.8 108328 8564 ? S 00:29 0:00 php/home/fdipzone/php/test.php
fdipzone 3047 0.0 0.0 4220 588? Ss 00:30 0:00/bin/sh-c php/home/fdipzone/php/test.php >>/home/fdipzone/php/test.log
Fdipzone 3048 1.3 0.8 108328 8560 ? S 00:30 0:00 php/home/fdipzone/php/test.php
fdipzone 3051 0.0 0.1 13148 1068 pts/0 S+ 00:30 0:00 grep--color=auto test.php
We want to finish the previous task, then perform the next task, and if the last task does not finish, the task does not execute until the next week, and if the last task completes, you can perform the next task.
Improvement methods
We can use a lock file to record whether the task is executing.
First, determine if the/tmp/mytest.lock exists, and if not, create, then perform the task, and then delete the lock file after the task has finished executing.
If the lock file already exists, quit the task.
<?php
$lockfile = '/tmp/mytest.lock ';
if (file_exists ($lockfile)) {
exit ();
} else{
file_put_contents ($lockfile, 1, true);
}
For ($i =0 $i <300; $i + +) {
echo date (' y-m-d h:i:s '). " \ r \ n ";
Sleep (1);
}
Unlink ($lockfile);
? >
This does guarantee that there will be no new tasks to execute during the execution of the task, but it is inconvenient to write the code in the task file for judgment. Is it possible to put mission-locked judgments beyond the task?
Use Linux flock file locks to achieve task locking, resolving conflicts
Format:
Flock [-sxun][-w #] Fd#
Flock [-sxon][-w #] file [-c] Command
Options
-S,--shared: get a shared lock-
x,--exclusive: Get an exclusive lock-
u,--unlock: Remove a lock, usually unwanted, and automatically discard the lock-n when the script finishes executing
- Nonblock: If you don't get a lock immediately, you fail directly instead of waiting for-
W,--timeout: If you don't get a lock immediately, wait for the specified time-
o,--close: Close the file's descriptor before running the command. For control-C, which is unlocked if the command produces a subprocess,
--command: run a separate command in the shell-
H,--help display Help-
V,--version: Display version
Continue with the first test.php, the file lock uses an exclusive lock, and if the lock fails, it does not wait. parameter is-XN
* * * * * flock-xn/tmp/mytest.lock-c ' php/home/fdipzone/php/test.php >>/home/fdipzone/php/test.log ' * * * * * *
This way, when the task is not completed, the next task determines that the/tmp/mytest.lock is locked, ends the current task, and then judges the next cycle.
This column more highlights: http://www.bianceng.cnhttp://www.bianceng.cn/OS/Linux/