/**
* 解析启动模式参数
* @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. linux移植常见问题

    *************1.给板子添加新的驱动**************** 一.       驱动程序编译进内核的步骤在 linux 内核中增加程序需要完成以下三项工作:1. 将编写的源代码复制 ...

  2. 获取cookie

    1.cookie是存储在用户本地终端的数据,实际上是一小段的文本信息 2.cookie的作用 帮助web站点保存有关的访问者的信息,方便用户的访问,如记住用户名和密码,实现自动登录功能案例:查看访问我 ...

  3. ELK 日志学习

    一.Elasticsearch 安装(所有的版本均使用5.5.0 ,且版需要相同 logstash \ kibana \ filebeat ) 官网下载地址:https://www.elastic.c ...

  4. Vue组成和第3方插件

    vue全家桶的成员是:vue-cli,vuex,vue-router,vue-axios(vue2.0). 第三方插件:vue-scroller,vue-lazyload,vue-awesome-sw ...

  5. The hyperlink for cell A2 references relation rId1, but that didn't exist!

    excel单元格中存在超链接,去掉 可以参考 https://www.cnblogs.com/songyunxinQQ529616136/p/6599523.html

  6. pandas_1

    大熊猫10分钟 这是对熊猫的简短介绍,主要面向新用户.您可以在Cookbook中看到更复杂的食谱. 通常,我们导入如下: In [1]: import numpy as np In [2]: impo ...

  7. TOJ 3151: H1N1's Problem(欧拉降幂)

    传送门:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=3151 时间限制(普通/Java): ...

  8. Cisco 4507R+E四引擎VSS故障解决

    如果可以要做双引擎VSS(每个机箱1个引擎), 3.6.7版本可以实现 如果需要做4引擎VSS(每个机箱2个引擎) 请使用3.8.x和之后的版本.

  9. 并发编程中Future和Callable使用

    Future模式非常适合在处理很耗时很长的业务逻辑时进行使用,可以有效的减少系统的响应时间,提高系统的吞吐量. 看一个小的demo: 看一下执行结果: 这是异步去获取结果的示例,在子线程去处理任务的时 ...

  10. HDU 3974 Assign the task(DFS序+线段树单点查询,区间修改)

    描述There is a company that has N employees(numbered from 1 to N),every employee in the company has a ...