linux的crontab命令,可以定时执行操作,最小周期是每分钟执行一次。关于crontab实现每秒执行可参考我之前的文章《linux crontab 实现每秒执行》现在有个问题,如果设定了任务每分钟执行一次,但有可能一分钟内任务并没有执行完成,这时系统会再执行任务。导致两个相同的任务在执行。
例如:
echo date ( 'Y-m-d H:i:s' ). "\r\n" ; |
循环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是否存在,如果不存在,则创建,然后执行任务,任务执行完后删除锁文件。
如果锁文件已经存在,则退出这次的任务。
$lockfile = '/tmp/mytest.lock' ; |
if (file_exists($lockfile)){ |
file_put_contents($lockfile, 1, true ); |
echo date ( 'Y-m-d H:i:s' ). "\r\n" ; |
这样的确可以保证任务执行其间不会有新任务执行,但这样需要在任务文件中写代码做判断,不方便。能不能把任务锁定的判断放在任务以外呢?
使用linux flock 文件锁实现任务锁定,解决冲突
格式:
选项
-u, --unlock: 移除一个锁,通常是不需要的,脚本执行完会自动丢弃锁 |
-n, --nonblock: 如果没有立即获得锁,直接失败而不是等待 |
-w, --timeout: 如果没有立即获得锁,等待指定时间 |
-o, --close: 在运行命令前关闭文件的描述符号。用于如果命令产生子进程时会不受锁的管控 |
-c, -- command : 在shell中运行一个单独的命令 |
继续用回第一个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 提供了 flock 命令来实现锁机制,该命令可以在 shell 脚本中设置锁,以控制对共享资源的访问。 flock 命令的基本格式有两种: 1. flock [-sxon] [-w timeout] lockfile [-c] command... 2. flock [-sxun] [-...
本文将深入探讨如何使用Shell脚本来实现文件锁功能,特别是排它锁,以防止脚本重复执行,确保数据安全和程序的正确性。 文件锁是多进程环境下控制资源访问的一种机制。在Linux系统中,当多个进程可能同时尝试修改同...
总之,Python中利用文件锁实现单例模式是一种有效的Linux系统下解决方案,但需要注意其局限性,如非跨平台兼容性和潜在的锁未释放问题。在设计多进程协作的系统时,理解并正确使用文件锁是至关重要的。
如果在shell脚本中使用,你可以将`flock`命令包裹在括号中,并通过重定向指定文件描述符来创建锁,如: ```bash ( flock -s 200 # ... commands executed under lock ... ) 200> /var/lock/mylockfile ``` 在这个...
文件锁分为记录锁(记录内部分锁)和共享锁(文件范围锁),通过flock()或fcntl()函数实现。理解文件锁的工作原理和正确使用,能确保并发访问文件的安全性。 4. **程序自启动**:在Linux系统中,程序自启动通常涉及...
为了确保数据的一致性,脚本可能还需要包含错误检查和异常处理机制,比如检查ID是否已存在,或者在写入文件时使用` flock`命令实现锁机制,防止并发访问引发的问题。 至于压缩包中的`myscript`文件,很可能是实现...
防止shell脚本重复执行是确保系统资源有效管理和避免并发问题的重要措施。在Linux或Unix环境中,通过锁机制可以实现这一目标。锁机制允许脚本实例在执行关键操作时互斥,确保同一时间只有一个实例在执行,其他实例则...
本文实例讲述了Python使用文件锁实现进程间同步功能。分享给大家供大家参考,具体如下: 简介 在实际应用中,会出现这种应用场景:希望shell下执行的脚本对某些竞争资源提供保护,避免出现冲突。本文将通过fcntl模块...
Linux中的文件锁可以通过flock、fcntl或lockf等函数实现,它们可以设置共享锁(读锁)和独占锁(写锁)。 "实验四-2310512018-曹婷婷.docx"和"实验四 进程通信操作.docx"可能探讨了Linux进程间通信(IPC)的主题。...
在PHP中,文件锁可以通过flock()函数来实现,这是一个高级的文件锁定功能,它使用Linux的fcntl()系统调用。flock()提供了两种锁类型:共享锁(LOCK_SH)和排他锁(LOCK_EX)。共享锁允许多个脚本同时读取文件,而...
描述中的"flock test.sh lock file"提到了一个特定的Shell命令`flock`,它用于在执行指定的命令或脚本(这里是`test.sh`)时获取文件锁,以确保在同一时间只有一个进程可以访问该文件,通常用于处理并发控制和避免...
echo "无法获取文件锁"; } fclose($fp); ``` 在此场景下,shell脚本可能通过定时任务或系统服务来启动和监控这个PHP后台进程,确保文件始终处于锁定状态。当然,实际应用中还需要考虑异常处理、错误恢复、资源释放...
常用的文件锁函数包括 `fcntl` 和 `flock`。 ```c int fcntl(int fd, int cmd, ...); int flock(int fd, int operation); ``` #### 二、文件系统 - **目录和文件**: 包括文件属性的查询 (`stat`)、文件类型和...
接着,使用flock函数尝试对该锁文件加锁,若加锁失败(意味着可能有其他进程已加锁),则终止脚本执行。 至于多进程的实现,则是通过修改锁文件的命名规则来实现的。这里用到了PHP内置的argc和argv参数,其中argc...
1. **文件锁(File Locking)**:在多进程环境中,为了防止多个进程同时读写同一文件导致的数据混乱,使用了`flock()`函数来实现文件锁。`flock()`可以设置为共享锁(LOCK_SH)或排他锁(LOCK_EX)。共享锁允许多个...