定时执行任务三种方式

转载至:http://www.jb51.net/article/27593.htm

crontab定时任务,nohup不挂断执行任务,守护进程,实现定时执行任务

Unix中 nohup 命令功能就是不挂断地运行命令,同时 nohup 把程序的所有输出到放到当前目录 nohup.out 文件中,如果文件不可写,则放到 <用户主目录>/nohup.out 文件中。那么有了这个命令以后我们php就写成shell 脚本使用循环来让我们脚本一直运行下去,不管我们终端窗口是否关闭都能够让我们php 脚本一直运行下去。

马上动手写个 PHP 小程序,功能为每30秒记录时间,写入到文件
复制代码 代码如下:

# vi for_ever.php
#! /usr/local/php/bin/php
define('ROOT', dirname(__FILE__).'/');
set_time_limit(0);
while (true) {
file_put_contents(ROOT.'for_ever.txt', date('Y-m-d H:i:s')."\n", FILE_APPEND);
echo date('Y-m-d H:i:s'), ' OK!';
sleep(30);
}
?>

保存退出,然后赋予 for_ever.php 文件可执行权限:
# chmod +x for_ever.php
让它在再后台执行:
# nohup /home/andy/for_ever.php.php &
记得最后加上 & 符号,这样才能够跑到后台去运行
执行上述命令后出现如下提示:
[1] 5157
nohup: appending output to 'nohup.out'
所有命令执行输出信息都会放到 nohup.out 文件中
这时你可以打开 for_ever.php 同目录下的 for_ever.txt 和 nohup.out 看看效果!
好了,它会永远运行下去了,怎么结束它呢?
# ps
PID TTY TIME CMD
4247 pts/1 00:00:00 bash
5157 pts/1 00:00:00 for_ever.php
5265 pts/1 00:00:00 ps
# kill -9 5157
找到进程号 5157 杀之,你将看到
[1]+ Killed nohup /home/andy/for_ever.php
OK!
====================
在很多项目中,或许有很多类似的后端脚本需要通过crontab定时执行。比如每10秒检查一下用户状态。脚本如下:
@file: /php_scripts/scan_userstatus.php
复制代码 代码如下:

#!/usr/bin/env php -q
$status = has_goaway();
if ($status) {
//done
}
?>

通过crontab定时执行脚本scan_userstatus.php
#echo “*:*/10 * * * * /php_scripts/scan_userstatus.php”
这样,每隔10秒钟,就会执行该脚本。
我们发现,在短时间内,该脚本的内存资源还没有释放完,又启用了新的脚本。也就是说:新脚本启动了,旧脚本占用的资源还没有如愿释放。如此,日积月累,浪费了很多内存资源。我们对这个脚本进行了一下改进,改进后如下:
@file: /php_scripts/scan_userstatus.php
复制代码 代码如下:

#/usr/bin/env php -q
while (1) {
$status = has_goaway();
if ($status) {
//done
}
usleep(10000000);
}
?>

这样,不需要crontab了。可以通过以下命令执行脚本,达到相同的功能效果
#chmod +x /php_scripts/scan_userstatus.php
#nohup /php_scripts/scan_userstatus.php &
在这里,我们通过&将脚本放到后台运行,为了防止随着终端会话窗口关闭进程被杀,我们使用了nohup命令。那么有没有办法,不使nohup命令,也能够运行呢,就像Unin/Linux Daemon一样。接下来,就是我们要讲的守护进程函数。
什么是守护进程?一个守护进程通常补认为是一个不对终端进行控制的后台任务。它有三个很显著的特征:在后台运行,与启动他的进程脱离,无须控制终端。常用的实现方式是fork() -> setsid() -> fork() 详细如下:
@file: /php_scripts/scan_userstatus.php
复制代码 代码如下:

#/usr/bin/env php -q
daemonize();
while (1) {
$status = has_goaway();
if ($status) {
//done
}
usleep(10000000);
}
function daemonize() {
$pid = pcntl_fork();
if ($pid === -1 ) {
return FALSE;
} else if ($pid) {
usleep(500);
exit(); //exit parent
}
chdir("/");
umask(0);
$sid = posix_setsid();
if (!$sid) {
return FALSE;
}
$pid = pcntl_fork();
if ($pid === -1) {
return FALSE;
} else if ($pid) {
usleep(500);
exit(0);
}
if (defined('STDIN')) {
fclose(STDIN);
}
if (defined('STDOUT')){
fclose(STDOUT);
}
if (defined('STDERR')) {
fclose(STDERR);
}
}
?>

实现了守护进程函数以后,则可以建立一个常驻进程,所以只需要执行一次:
#/php_scripts/scan_userstatus.php
这里较为关键的二个php函数是pcntl_fork()和posix_setsid()。fork()一个进程,则表示创建了一个运行进程的副本,副本被认为是子进程,而原始进程被认为是父进程。当fork()运行之后,则可以脱离启动他的进程与终端控制等,也意味着父进程可以自由退出。 pcntl_fork()返回值,-1表示执行失败,0表示在子进程中,而返进程ID号,则表示在父进程中。在这里,退出父进程。setsid(),它首先使新进程成为一个新会话的“领导者”,最后使该进程不再控制终端,这也是成为守护进程最关键的一步,这意味着,不会随着终端关闭而强制退出进程。对于一个不会被中断的常驻进程来说,这是很关键的一步。进行最后一次fork(),这一步不是必须的,但通常都这么做,它最大的意义是防止获得控制终端。(在直接打开一个终端设备,而且没有使用O_NOCTTY标志的情况下, 会获得控制终端).
其它事项说明:
1) chdir() 将守护进程放到总是存在的目录中,另外一个好处是,你的常驻进程不会限制你umount一个文件系统。
2)umask() 设置文件模式,创建掩码到最大的允许限度。如果一个守护进程需要创建具有可读,可写权限的文件,一个被继承的具有更严格权限的掩码会有反作用。
3)fclose(STDIN), fclose(STDOUT), fclose(STDERR) 关闭标准I/O流。注意,如果有输出(echo),则守护进程会失败。所以通常将STDIN, STDOUT, STDERR重定向某个指定文件.
一款定时/循环执行任务的绿色小软件,可以用来定时执行程序、DOS命令、从HTTP服务器下载程序运行、结束进程、 模拟按键、发送EMAIL、网络唤醒、消息提示、关机、重启、注销、锁定、待机等操作,都是本人曾经所需要的功能!   合理使用和搭配软件的各功能,可做更多事情!可供对系统较了解的人自由发挥。 提示: a. 显示主窗口热键Ctrl+F1(可在设置里自定义) b. OnTimer.exe /h 启动隐藏,但不隐藏托盘图标除非使用OnTimer.exe /h-all c. 如果想更改消息提示背景只要找张238x139(其他尺寸软件会缩放)的图片替换OnTimer.jpg d. 普通运行、参数运行、 执行DOS “备注”开头为“-h”则隐藏执行 e. 关机、重启、注销、锁定、待机 “内容”开头为数字则执行前倒计时(可选择取消) 1.普通运行:  可以打开程序,目录,网站,文件,和Windows运行一样,只是不能带参数 如: [内容]http://www.yryz.net [内容]d:\mp3\爱上你是个错.mp3(可实现音乐闹钟) 2.参数运行: 可以带参数运行程序 如: [内容]shutdown -s [内容]ping www.baidu.com 3.下载运行:你可以从网上下载文件并执行 如: [内容]http://www.yryz.net/soft/OnTimer.rar [内容]http://dl_dir.qq.com/qqfile/qq/QQ2009/qq2009sp6_installer.exe 4.结束进程: 以最高权限结束进程,可以结束系统进程(winlogon.exe)! 如: [内容]QQ.exe 5.执行DOS: 就是CMD啦(dir del ...) [内容]del c:\*.log /q /s 6.模拟按键: 用来发送按键(附录有相关按键说明) 如: [内容]^%z 相当于按了Ctrl+Alt+z ,QQ出来了吧!…… 7.发送邮件: 用来定时发送Email的,当然你要先设置好SMTP,也就是用来发信的账号,然后就可以添加任务了, [内容]邮件内容 [参数]收信地址 注意: 如果你只是想发送文字,就直接在[内容]中输入,如: 生日快乐! 如果是想发送文本文件,那就在[内容]中输入文件路径如:c:\boot.ini 程序执行此操作时,会先内容是否为存在的文件,否则就把内容当作文字发送! 8.网络唤醒:  用来远程开机,[内容]中输入MAC地址如:00-e0-4d-df-7e-8a 9.消息提示:  用来定时提醒的,在屏幕的右下角以动画形式显示. 10.关闭系统 11.重启系统 12.注销登陆 13.锁定系统 14.系统待机 例: ------------------------ 先: 执行DOS: ipconfig /all >c:\ip.txt 再: 发送邮件: c:\ip.txt 可用于获得ADSL的动态IP,知道的人应该了解用处! ---------------------------------- 20110330 v1.3d - 修复在Windows 7下按“Alt”键按钮消失的BUG - 修复权限问题导致“随系统启动”无效 20101205 v1.3c + 关机等任务支持倒计时,以便取消执行 * 优化列表显示效果 20101128 v1.3b + 普通运行、参数运行、 执行DOS 支持隐藏执行 + 双击任务即可编辑 - 修复“移动”->“尾部”报错 - 修复分类切换时,任务状态显示不正确 * 调整执行次数显示 20101125 v1.3a + 支持任务分类管理(可拖动) + 支持“每月”任务 + 支持任务排序(上下移动任务,可拖动) + 支持任务执行次数存储 + 支持“内容”、“参数/备注”搜索 + 支持临时暂停所有任务 * 一些细节改进和BUG修复 ! 因数据库结构有变动,要使用原来的数据库(OnTimer.db),可执行 OnTimer.exe /update,当然出现异常时软件也会提示你修复. 20101020 v1.2h - 修复软件中文目录支持问题(数据库读取异常) - 修复托盘图标重建问题 + 添加任务状态托盘提示(活动任务/总任务) * 调整显示字体和列表排序 20101018 v1.2g + 加入“系统待机”功能 + 设置中加入“随系统启动”选项 + 任务列表支持点击“表头”进行排序 + 支持给任务添加备注 * 优化一些小细节 - 修复Win7下添加任务时提示“时间格式有误”的BUG 20100903 v1.2f * 优化消息提示框,使其提示消息时不影响你的工作 * 调整了任务类型的顺序,可能会导致旧版任务类型不正常,更新时请注意 * 调整任务列表顺序,把新添加的任务放到最前面 20100623 v1.2e * 改进列表选择框 * 窗口焦点设置(热键唤醒时) - 去掉提示消息窗口自动关闭 + 可自定义热键 ! 因数据库结构有变动,使用 OnTime.exe /12d-12e 启动就可把旧版的数据库转换成v1.2e版 20100511 v1.2d % 解决多任务时列表闪烁问题。 % 修复计时部分一些Bug!(星期) 20100510 v1.2c + 加入按星期执行!并优化计时部分。 20100510 v1.2b * 重写,效果更好,并作大量优化!  + 使用加密SQLite存储数据。 2008 v1.2  边学边做自己用。 按键附录: Shift + Ctrl ^ Alt % Enter ~ 以下按键要用{}括起来: BKSP, BS, BACKSPACE BREAK CAPSLOCK CLEAR DEL DELETE DOWN END ENTER ESC ESCAPE F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 HELP HOME INS LEFT NUMLOCK PGDN PGUP PRTSC RIGHT SCROLLLOCK TAB UP WIN ( ) ~ % ^ + 可参考下例重复发送某按键: {DEL 4} ;连续4次按下 DEL 键 {S 30} ;发送30个字符“S” +{TAB 4} ;连续4次按下 SHIFT+TAB -------------------------------------------------------- SendMail.log是的日志代码,可参考下表 邮件服务返回代码含义 500 格式错误,命令不可识别(此错误也包括命令行过长) 501 参数格式错误 502 命令不可实现 503 错误的命令序列 504 命令参数不可实现 211 系统状态或系统帮助响应 214 帮助信息 220 服务就绪 221 服务关闭传输信道 421 服务未就绪,关闭传输信道(当必须关闭时,此应答可以作为对任何命令的响应) 250 要求的邮件操作完成 251 用户非本地,将转发向 450 要求的邮件操作未完成,邮箱不可用(例如,邮箱忙) 550 要求的邮件操作未完成,邮箱不可用(例如,邮箱未找到,或不可访问) 451 放弃要求的操作;处理过程中出错 551 用户非本地,请尝试 452 系统存储不足,要求的操作未执行 552 过量的存储分配,要求的操作未执行 553 邮箱名不可用,要求的操作未执行(例如邮箱格式错误) 354 开始邮件输入,以.结束 554 操作失败 535 用户验证失败 235 用户验证成功 334 等待用户输入验证信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值