本文要写的Linux定时处理程序,想必这是很多Linux开发人员需要处理的问题。例如编写一个每天数据入库程序,编写一个定时邮件通知程序等等。
对于定时处理程序,主要有两种方法可以实现。一种是使用crontab来做程序的定时启动,实现定时处理功能,一种是通过守护进程,间隔一段时间处理一次。
下面对这两种实现做一些分析。
crontab 是用来设置被周期性执行的指令。可以设置每隔一段时间执行一次程序,执行的方法是新建一个进程来进行处理。通过编写一个cronfile定时处理文件即可,例如每隔20分钟,执行一个backup操作:
*/20 * * * * /usr/bin/backup
程序会在0分,20分,40分的时候启动一个/usr/bin/backup进程。
crontab的优点是可以指定确切的时间点启动程序,可以准确控制每次执行的间隔(两次开始执行程序的时间间隔)。但是由于crontab每次是通过新建一个进程来进行处理,如果间隔时间太短以至于上一个进程还未处理完,却已启动第二次处理,这时两个同样的进程在运行,必定就有一些资源的竞争和冲突。如果通过进程本身的程序区兼容这种竞争,会让程序变得过于复杂。如果是对执行时间点没有很高要求,可以在每次启动程序时先做进程检查,如果检查到上次程序还未处理完,跳过本次处理或者延后本次处理时间。crontab的另一个缺点就是无法监控到定时程序的执行(有的程序处理时间只有零点几秒,难以进行定时扫描)。如果由于crontab本身漏洞或是系统本身问题引起crontab失效(生产机器发生过这种问题),这对于排查问题是比较麻烦的。
编写定时程序的另一个方式是通过守护进程来实现,守护进程是一种脱离终端并且在后台运行的进程。用守护方式来编写定时程序就如:
while(true) { process..... sleep(SLEEP_TIME); }原理就是一个死循环,每次处理完之后休眠一段时间,再进行下一次处理。这种实现方式的好处就是可以避开资源的竞争,因为处理都是顺序进行,处理完一次之后才进行下一次处理。并且守护进程是比较好监控,它是一个常驻内存的程序,只需定时扫描进程就可很好监控程序的执行。拥有常驻内存的特性,这可以大大减少数据的载入操作,一次载入,永久使用。
当然,编写守护程序来实现定时也有一些缺点,它并不适用于需要在确切时间点启动的程序(例如需要每天8点钟定时运行的程序),只能适合周期性,但是对运行时间点没有要求的处理。并且守护进行处理不能准确控制每次处理的间隔,它只能控制上次处理结束到下次启动的间隔。
总的来说,这两个处理方式都能实现定时处理的任务,但是对于定时意义,还是有所差别。crontab的定时,是确定每一次执行时间点,每次启动进程的间隔一致;而守护进程的定时,是确定上一次处理结束到下一次处理结束的时间间隔。使用时需要根据具体使用场景选择。crontab在定时处理上,相对灵活一些,但需要注意资源竞争以及对执行的监控。而守护进程,效率相对高一些,并且方便监控,但需确定程序对于执行时间点是否有较高的要求。