`

linux使用flock文件锁解决脚本重复执行问题

阅读更多

linux的crontab命令,可以定时执行操作,最小周期是每分钟执行一次。关于crontab实现每秒执行可参考我之前的文章《linux crontab 实现每秒执行》现在有个问题,如果设定了任务每分钟执行一次,但有可能一分钟内任务并没有执行完成,这时系统会再执行任务。导致两个相同的任务在执行。

例如:

<?
// test.php
for($i=0; $i<300; $i++){
    echo date('Y-m-d H:i:s')."\r\n";
    sleep(1);
}
?>

循环300次,每循环一次睡眠1秒。执行完成需要300秒即5分钟。

设置crontab 为每分钟执行

* * * * * php /home/fdipzone/php/test.php >> /home/fdipzone/php/test.log

2分钟后,使用 ps aux|grep test.php 查看,可以看到有两个test.php进程在执行。

3分钟后,看到有3个test.php进程在执行。

fdipzone@ubuntu:/tmp$ ps aux|grep test.php
fdipzone  2995  0.0  0.0   4220   588 ?        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

 

我们是希望执行完上一任务,再执行下一任务,如果上一任务未执行完成,则这次的任务不执行,直到下一周期再判断,如果上一任务执行完成,则可以执行下一任务。

改进方法

我们可以使用一个锁文件,来记录任务是否执行中。

首先判断/tmp/mytest.lock是否存在,如果不存在,则创建,然后执行任务,任务执行完后删除锁文件。

如果锁文件已经存在,则退出这次的任务。

 

<?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);
?>

 

这样的确可以保证任务执行其间不会有新任务执行,但这样需要在任务文件中写代码做判断,不方便。能不能把任务锁定的判断放在任务以外呢?

使用linux flock 文件锁实现任务锁定,解决冲突

格式:

flock [-sxun][-w#] fd#
flock [-sxon][-w#] file [-c] command

 

选项

-s, --shared:    获得一个共享锁
-x, --exclusive: 获得一个独占锁
-u, --unlock:    移除一个锁,通常是不需要的,脚本执行完会自动丢弃锁
-n, --nonblock:  如果没有立即获得锁,直接失败而不是等待
-w, --timeout:   如果没有立即获得锁,等待指定时间
-o, --close:     在运行命令前关闭文件的描述符号。用于如果命令产生子进程时会不受锁的管控
-c, --command:   在shell中运行一个单独的命令
-h, --help       显示帮助
-V, --version:   显示版本

 

继续用回第一个test.php,文件锁使用独占锁,如果锁定则失败不等待。参数为-xn

* * * * * flock -xn /tmp/mytest.lock -c 'php /home/fdipzone/php/test.php >> /home/fdipzone/php/test.log'

这样当任务未执行完成,下一任务判断到/tmp/mytest.lock被锁定,则结束当前的任务,下一周期再判断。

转自:http://blog.csdn.net/fdipzone/article/details/38284009

分享到:
评论

相关推荐

    Linux下在shell脚本中设置锁的命令

    Linux 提供了 flock 命令来实现锁机制,该命令可以在 shell 脚本中设置锁,以控制对共享资源的访问。 flock 命令的基本格式有两种: 1. flock [-sxon] [-w timeout] lockfile [-c] command... 2. flock [-sxun] [-...

    shell脚本实现文件锁功能

    本文将深入探讨如何使用Shell脚本来实现文件锁功能,特别是排它锁,以防止脚本重复执行,确保数据安全和程序的正确性。 文件锁是多进程环境下控制资源访问的一种机制。在Linux系统中,当多个进程可能同时尝试修改同...

    python 利用文件锁单例执行脚本的方法

    总之,Python中利用文件锁实现单例模式是一种有效的Linux系统下解决方案,但需要注意其局限性,如非跨平台兼容性和潜在的锁未释放问题。在设计多进程协作的系统时,理解并正确使用文件锁是至关重要的。

    如何在Linux中使用flock控制程序的异步执行

    如果在shell脚本中使用,你可以将`flock`命令包裹在括号中,并通过重定向指定文件描述符来创建锁,如: ```bash ( flock -s 200 # ... commands executed under lock ... ) 200&gt; /var/lock/mylockfile ``` 在这个...

    linux_gdb——sgi_stl——文件锁——程序自动重启

    文件锁分为记录锁(记录内部分锁)和共享锁(文件范围锁),通过flock()或fcntl()函数实现。理解文件锁的工作原理和正确使用,能确保并发访问文件的安全性。 4. **程序自启动**:在Linux系统中,程序自启动通常涉及...

    linux 人事管理脚本

    为了确保数据的一致性,脚本可能还需要包含错误检查和异常处理机制,比如检查ID是否已存在,或者在写入文件时使用` flock`命令实现锁机制,防止并发访问引发的问题。 至于压缩包中的`myscript`文件,很可能是实现...

    防止shell脚本重复执行的代码

    防止shell脚本重复执行是确保系统资源有效管理和避免并发问题的重要措施。在Linux或Unix环境中,通过锁机制可以实现这一目标。锁机制允许脚本实例在执行关键操作时互斥,确保同一时间只有一个实例在执行,其他实例则...

    Python使用文件锁实现进程间同步功能【基于fcntl模块】

    本文实例讲述了Python使用文件锁实现进程间同步功能。分享给大家供大家参考,具体如下: 简介 在实际应用中,会出现这种应用场景:希望shell下执行的脚本对某些竞争资源提供保护,避免出现冲突。本文将通过fcntl模块...

    Linux作业.zip

    Linux中的文件锁可以通过flock、fcntl或lockf等函数实现,它们可以设置共享锁(读锁)和独占锁(写锁)。 "实验四-2310512018-曹婷婷.docx"和"实验四 进程通信操作.docx"可能探讨了Linux进程间通信(IPC)的主题。...

    PHP程序中的文件锁、互斥锁、读写锁使用技巧解析

    在PHP中,文件锁可以通过flock()函数来实现,这是一个高级的文件锁定功能,它使用Linux的fcntl()系统调用。flock()提供了两种锁类型:共享锁(LOCK_SH)和排他锁(LOCK_EX)。共享锁允许多个脚本同时读取文件,而...

    z.tar_shell_

    描述中的"flock test.sh lock file"提到了一个特定的Shell命令`flock`,它用于在执行指定的命令或脚本(这里是`test.sh`)时获取文件锁,以确保在同一时间只有一个进程可以访问该文件,通常用于处理并发控制和避免...

    PHP后台循环锁定文件.zip_PHP后台循环_php文件锁定_shell_锁定

    echo "无法获取文件锁"; } fclose($fp); ``` 在此场景下,shell脚本可能通过定时任务或系统服务来启动和监控这个PHP后台进程,确保文件始终处于锁定状态。当然,实际应用中还需要考虑异常处理、错误恢复、资源释放...

    Linux系统编程学习笔记

    常用的文件锁函数包括 `fcntl` 和 `flock`。 ```c int fcntl(int fd, int cmd, ...); int flock(int fd, int operation); ``` #### 二、文件系统 - **目录和文件**: 包括文件属性的查询 (`stat`)、文件类型和...

    php中实现进程锁与多进程的方法

    接着,使用flock函数尝试对该锁文件加锁,若加锁失败(意味着可能有其他进程已加锁),则终止脚本执行。 至于多进程的实现,则是通过修改锁文件的命名规则来实现的。这里用到了PHP内置的argc和argv参数,其中argc...

    php使用多个进程同时控制文件读写示例

    1. **文件锁(File Locking)**:在多进程环境中,为了防止多个进程同时读写同一文件导致的数据混乱,使用了`flock()`函数来实现文件锁。`flock()`可以设置为共享锁(LOCK_SH)或排他锁(LOCK_EX)。共享锁允许多个...

Global site tag (gtag.js) - Google Analytics