|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
小试一下身手,大概是没问题了,那么交给你个任务,做个留言本吧,这和HELLO WORLD有一比啊!^_^,同是新手面临的第一道关。 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重定向某个指定文件.没有人会喜欢和见异思迁的人交朋友,因为这种人太不安分,太不可靠,因此,你必须要强迫自己完成自己的目标,哪怕可能会很难受,也得坚持,毅力就是这么锻炼出来的。 |
|