WorkerMan::Worker类解析(3)
来源:互联网 发布:北塔软件怎么样 编辑:程序博客网 时间:2024/06/05 11:26
// 把运行的脚本变为守护进程 protected static function daemonize() { if (!self::$daemonize) { return; } umask(0); // 创建子进程. $pid = pcntl_fork(); if (-1 === $pid) { throw new Exception('fork fail'); } elseif ($pid > 0) { // 结束父进程. exit(0); } // 使当前子进程成为会话组长. if (-1 === posix_setsid()) { throw new Exception("setsid fail"); } // Fork again avoid SVR4 system regain the control of terminal. // 再次fork子进程,使进程完全脱离终端,成为守护进程. $pid = pcntl_fork(); if (-1 === $pid) { throw new Exception("fork fail"); } elseif (0 !== $pid) { exit(0); } }核心代码:$pid = pcntl_fork();posix_setsid()$pid = pcntl_fork();
// 初始化worker数据. protected static function initWorkers() { // 遍历所有的worker. foreach (self::$_workers as $worker) { // 如果worker名字不存在,则给予一个初始值. if (empty($worker->name)) { $worker->name = 'none'; } // 获取最大的worker名称长度. $worker_name_length = strlen($worker->name); if (self::$_maxWorkerNameLength < $worker_name_length) { self::$_maxWorkerNameLength = $worker_name_length; } // 获取最长的socket名称长度. $socket_name_length = strlen($worker->getSocketName()); if (self::$_maxSocketNameLength < $socket_name_length) { self::$_maxSocketNameLength = $socket_name_length; } // Get unix user of the worker process. // 如果运行用户没有设置,那么把当前运行用户作为运行用户. if (empty($worker->user)) { $worker->user = self::getCurrentUser(); } else { // 如果不是root用户,并且设置的用户和当前运行脚本用户不匹配,则给出一个警告信息. // posix_getuid() 获取当前运行用户的id, root用户的id=0. if (posix_getuid() !== 0 && $worker->user != self::getCurrentUser()) { self::log('Warning: You must have the root privileges to change uid and gid.'); } } // Get maximum length of unix user name. $user_name_length = strlen($worker->user); if (self::$_maxUserNameLength < $user_name_length) { self::$_maxUserNameLength = $user_name_length; } // Listen. // 创建worker监听. if (!$worker->reusePort) { $worker->listen(); } } }1. posix_getuid() 获取运行脚本的当前uid (root用户的uid=0) // 获取当前运行脚本的用户名. protected static function getCurrentUser() { // 获取当前运行用户的用户名. // posix_getpwuid 根据用户id获取用户信息. $user_info = posix_getpwuid(posix_getuid()); return $user_info['name']; }1. posix_getpwuid() 根据用户的uid获取用户的信息.
// worker进行监听. public function listen() { if (!$this->_socketName) { return; } // Autoload. // 设置自动加载路径. Autoloader::setRootPath($this->_autoloadRootPath); if (!$this->_mainSocket) { // Get the application layer communication protocol and listening address. // 切割出协议和地址. list($scheme, $address) = explode(':', $this->_socketName, 2); // Check application layer protocol class. // 是否为内置协议,不是内置协议需要加载协议的定义. if (!isset(self::$_builtinTransports[$scheme])) { $scheme = ucfirst($scheme); /** * 协议可能存在的目录. * Project\Protocols\... * Project\WorkerMan\Protocols\... */ $this->protocol = '\\Protocols\\' . $scheme; if (!class_exists($this->protocol)) { $this->protocol = "\\Workerman\\Protocols\\$scheme"; // 自定义协议处理不存在,抛出错误. if (!class_exists($this->protocol)) { throw new Exception("class \\Protocols\\$scheme not exist"); } } // 自定义的协议默认都走tcp. if (!isset(self::$_builtinTransports[$this->transport])) { throw new \Exception('Bad worker->transport ' . var_export($this->transport, true)); } } else { $this->transport = $scheme; } $local_socket = self::$_builtinTransports[$this->transport] . ":" . $address; // Flag. $flags = $this->transport === 'udp' ? STREAM_SERVER_BIND : STREAM_SERVER_BIND | STREAM_SERVER_LISTEN; $errno = 0; $errmsg = ''; // SO_REUSEPORT. // 端口复用-php7才能使用. if ($this->reusePort) { stream_context_set_option($this->_context, 'socket', 'so_reuseport', 1); } // Create an Internet or Unix domain server socket. // 创建服务端server的socket监听. $this->_mainSocket = stream_socket_server($local_socket, $errno, $errmsg, $flags, $this->_context); if (!$this->_mainSocket) { throw new Exception($errmsg); } if ($this->transport === 'ssl') { stream_socket_enable_crypto($this->_mainSocket, false); } elseif ($this->transport === 'unix') { $socketFile = substr($address, 2); if ($this->user) { chown($socketFile, $this->user); } if ($this->group) { chgrp($socketFile, $this->group); } } // Try to open keepalive for tcp and disable Nagle algorithm. // if (function_exists('socket_import_stream') && self::$_builtinTransports[$this->transport] === 'tcp') { // 将stream转换为socket对象. $socket = socket_import_stream($this->_mainSocket); // 设置socket属性keepalive和禁用Nagle. @socket_set_option($socket, SOL_SOCKET, SO_KEEPALIVE, 1); @socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1); } // 非阻塞模式. stream_set_blocking($this->_mainSocket, 0); } // 注册监听(self::$globalEvent但是这里此变量=null,所有是不会执行的). $this->resumeAccept(); }1. $this->_mainSocket = stream_socket_server($local_socket, $errno, $errmsg, $flags, $this->_context); // 创建socket监听
阅读全文
0 0
- WorkerMan::Worker类解析(3)
- WorkerMan::Worker类解析(1)
- WorkerMan::Worker类解析(2)
- WorkerMan::Worker类解析(4)
- WorkerMan::Timer解析
- Workerman
- Workerman
- workerman
- Workerman
- Spark Worker原理解析
- Worker::setProcessTitle()解析
- Worker::initId()解析
- C语言实现类workerman的功能
- Worker
- spark worker的原理和源码解析
- 3supervisor启动worker源码分析-worker.clj
- workerman 定时器
- workerman推送
- 下拉刷新和加载更多
- dubbo的一些默认变量
- Teradata中fastload使用
- [agc010f]Tree Game
- caffe之利用mnist数据集训练好的lenet_iter_10000.caffemodel模型测试一张自己的手写体数字
- WorkerMan::Worker类解析(3)
- win10下usb rndis驱动配置
- FASTLOAD的使用
- Uva-1289 Stacking Plates
- postman中 form-data、x-www-form-urlencoded、raw、binary的区别
- install openni2 on ubuntu
- foreach语句使用总结
- python平台下实现xgboost算法及输出的解释
- 今天写了一条把我两个月职业生涯学到的SQL知识全用上了的语句