/**
* 解析启动模式参数
* @param $opt
*/
static public function params_s($opt)
{
//判断传入了s参数但是值,则提示错误
if ((isset($opt["s"]) && !$opt["s"]) || (isset($opt["s"]) && !in_array($opt["s"], array("start", "stop", "restart")))) {
Main::log_write("Please run: path/to/php main.php -s [start|stop|restart]");
} if (isset($opt["s"]) && in_array($opt["s"], array("start", "stop", "restart"))) {
switch ($opt["s"]) {
case "start":
Crontab::start();
break;
case "stop":
Crontab::stop();
break;
case "restart":
Crontab::restart();
break;
}
}
}

 这里我们先分析Crontab::start()

  从这个意思我们应该知道这应该是进程启动的方法

因为crontab自己注册了引入方法,所以方法在include/Crontab.class.php中

/**
* 启动
*/
static public function start()
{
if (file_exists(self::$pid_file)) {
die("Pid文件已存在!\n");
}
self::daemon();
self::set_process_name();
self::run();
Main::log_write("启动成功");
}

  先检查pid文件是否存在,如果存在说明进程已经启动不能再次开始

self::daemon(); 在上一节,如果params_d($opt) 开启守护进程会执行swoole_process::daemon();//传送门:https://wiki.swoole.com/wiki/page/273.html

self::set_process_name();//设置进程名字 这里没有支持用户自己命名,名字为:lzm_Master

接下来执行run方法:

 /**
* 运行
*/
static protected function run()
{
self::$tasksHandle = new LoadTasks(strtolower(self::$taskType), self::$taskParams);
self::register_signal();
if (self::$checktime) {
$run = true;
Main::log_write("正在启动...");
while ($run) {
$s = date("s");
if ($s == 0) { Crontab::load_config();
self::register_timer();
$run = false;
} else {
Main::log_write("启动倒计时 " . (60 - $s) . " 秒");
sleep(1);
}
}
} else {
self::load_config();
self::register_timer();
}
self::get_pid();
self::write_pid();
//开启worker
if (self::$worker) {
(new Worker())->loadWorker();
}
}

  106行:self::$tasksHandle = new LoadTasks(strtolower(self::$taskType), self::$taskParams);//这里我们就分析LoadTasksByFile,这里放到下一讲

  107行:self::register_signal();//注册信号,用来处理进程退出

如果在客户端进行ctrl+c退出的话,会发送SIGINT信号,但是这里没做处理,那么请不要在客户端直接ctrl+c退出程序,不然的话下次就需要执行重启命令了,因为不退出

  如果受到退出信号SIGTERM就会直接调用exit2p:删除掉pid文件然后直接exit退出

还需要处理当子进程退出,为了不让程序变成僵尸进程需要进行wait处理

  这里是先判断是否在tasklist中pid是否存在,如果存在这个任务,则直接将子进程关闭,如果这个任务还有unique_list值(这里是任务里的排他数量的意思)会进行自减,杀死后扣除1,如果在load_config中会继续往taskTabel插入任务,争用这个unique字段
       如果是工作进程,那么复制一份work进程

  至于SIGUSR1信号,这里本来是应该是重新加载配置文件的,不知道为什么这里没有加上实现

/**
* 注册信号
*/
static private function register_signal()
{
swoole_process::signal(SIGTERM, function ($signo) {
self::exit2p("收到退出信号,退出主进程");
});
swoole_process::signal(SIGCHLD, function ($signo) {
while ($ret = swoole_process::wait(false)) {
$pid = $ret['pid'];
if (isset(self::$task_list[$pid])) {
$task = self::$task_list[$pid];
if ($task["type"] == "crontab") {
$end = microtime(true);
$start = $task["start"];
$id = $task["id"];
Main::log_write("{$id} [Runtime:" . sprintf("%0.6f", $end - $start) . "]");
$task["process"]->close();//关闭进程
unset(self::$task_list[$pid]);
if (isset(self::$unique_list[$id]) && self::$unique_list[$id] > 0) {
self::$unique_list[$id]--;
}
}
if ($task["type"] == "worker") {
$end = microtime(true);
$start = $task["start"];
$classname = $task["classname"];
Main::log_write("{$classname}_{$task["number"]} [Runtime:" . sprintf("%0.6f", $end - $start) . "]");
$task["process"]->close();//关闭进程
(new Worker())->create_process($classname, $task["number"], $task["redis"]);
}
}
};
});
swoole_process::signal(SIGUSR1, function ($signo) {
//TODO something
}); }

  这些都执行后,会执行Crontab::load_config();

该方法会读取到我们配置文件的读取路径中的数据,在main.php里面params_c方法会默认从ROOT_PATH . "config/crontab.php"中获取

  Crontab.class.php:line162->ParseCrontab::parse($task["rule"], $time);//这里是解析定时任务的规则返回值是每个任务的下次执行的间隔(秒级),类似linux自带的crontab的规则,这个放到后面讲解

  TickTable::set_task($ret, array_merge($task, array("id" => $id)));//这里会将读取到任务的规则写到ticktable里面
  self::register_timer();//这里才是任务调度的关键,每隔1分钟会将到下一分钟需要执行的任务插入到ticktable里面,然后每隔1s钟执行task

 下一讲:do_something方法

分析params_s方法的更多相关文章

  1. 网友"就像一支烟"山寨币分析估值方法

    [注:素材取自QQ群,2017年12月28日的聊天记录."就像一支烟"分享了自己的山寨币分析估值方法.因为删去了其他人的聊天记录,部分文字可能断章取义,仅供参考,具体情况请自行分析 ...

  2. [C语言] 数据结构-算法效率的度量方法-事前分析估算方法

    事前分析估算方法:在计算机程序编制前,依据统计方法对算法进行估算,抛开与计算机硬件软件有关的因素,一个程序的运行时间,依赖于算法的,好坏和问题的输入规模,所谓问题输入规模是指输入量的多少 推导过程,比 ...

  3. requirejs源码分析: requirejs 方法–2. context.require(deps, callback, errback);

    上一篇 requirejs源码分析: requirejs 方法–1. 主入口  中的return context.require(deps, callback, errback);  调用的是make ...

  4. 通过混合编程分析的方法和机器学习预测Web应用程序的漏洞

    通过混合编程分析的方法和机器学习预测Web应用程序的漏洞 由于时间和资源的限制,web软件工程师需要支持识别出有漏洞的代码.一个实用的方法用来预测漏洞代码可以提高他们安全审计的工作效率.在这篇文章中, ...

  5. 日志分析方法概述 & Web日志挖掘分析的方法

    日志在计算机系统中是一个非常广泛的概念,任何程序都有可能输出日志:操作系统内核.各种应用服务器等等.日志的内容.规模和用途也各不相同,很难一概而论. 本文讨论的日志处理方法中的日志,仅指Web日志.其 ...

  6. mybatis源码分析(方法调用过程)

    十一月月底,宿舍楼失火啦,搞得20多天没有网,目测直到放假也不会来了... 正题 嗯~,其实阅读源码不是为了应付面试,更重要的让你知道,大师是怎样去写代码的,同样是用Java,为啥Clinton Be ...

  7. tomcat启动(三)Catalina分析-load方法分析

    load()方法按从上到下顺序分析(主要分析本人所没学过的知识点,其它略过...). Digester类作用 使用sax技术对xml进行解析 未开始解析时Digester.push(this)这个用来 ...

  8. requirejs源码分析: requirejs 方法–1. 主入口

    该方法是 主要的入口点 也是最常用的方法. req = requirejs = function (deps, callback, errback, optional) { //Find the ri ...

  9. 【转载】WEB系统性能问题的分析定位方法

    以一个典型的WEB系统来举例,性能问题一般体现在客户端请求后的响应时间上.在性能测试过程中,即压力增大到某个程度后,响应时间指标迅速增长.但如那篇文章所说,这只能叫做一个现象,测试人员需要找到问题所在 ...

随机推荐

  1. ubuntu 下安装和启动SSH 服务

    安装OPENSSH 服务端 sudo apt-get install openssh-server 查看进程是否启动 ps -e | grep ssh 删除密钥文件 rm /etc/ssh/ssh_h ...

  2. C# 递归获取 文件夹的 所有文件

    public void Director(string dir, List<string> list) { DirectoryInfo d = new DirectoryInfo(dir) ...

  3. Ubuntu下好的PDF阅读器介绍

    我们经常要学习,看论文,如果有好的PDF阅读器,可以做笔记,对以后查看和记忆是有帮助的 这里推荐用:okular 这里是基本操作哦 1: 安装 sudo apt-get install okular ...

  4. mysql攻防之写入漏洞

    因为被别人利用mysql攻击,所以想在这里帮助大家提高一下自身mysql的安全.避免成为别人的肉鸡. show global variables like '%secure%'; 如果是这样则黑客可以 ...

  5. 分享一个 Java String split 快速分割的方法

    java中string.split() 方法比较强大,但是split()方法采用正则表达式,速度相对会慢一点, 其实大多数场景下并不需要使用正则表达式,下面分享一个不使用正则表达式分隔字符串的方法. ...

  6. metasploitable使用

    DVWA默认的用户有5个,用户名密码如下(一个足以): admin/password gordonb/abc123 1337/charley pablo/letmein smithy/password

  7. Java读取文件-BufferedReader/FileReader/InputStreamReader/FileInputStream的关系和区别

    一.Java读取和存储文件数据流 Java读取文件,实际是将文件中的字节流转换成字符流输出到屏幕的过程   这里面涉及到两个类:InputStreamReader和OutputStreamWriter ...

  8. STL::map/multimap

    map: 默认根据 key 排序(从小到大),能够通过 backet operator(operator [ ]) 来获取元素,内部由二叉搜索树来实现(binary search trees). mu ...

  9. ansible1

    前期工作: 第一步:下载epel源 wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo 第二步: ...

  10. white-space和word-wrap和word-break所表示的换行和不换行的区别

    一.前言 使得文本换行有很多方式, <br/>标签元素,能够强制使得所在位置文本换行 <p>元素,<div>设定宽度,都可以对文本内容实现自适应换行 对于长单词或者 ...