Ejemplo n.º 1
0
 /**
  * 创建一个worker进程
  * @param string $worker_name 服务名
  * @return int 父进程:>0得到新worker的pid ;<0 出错; 子进程:始终为0
  */
 protected static function createOneWorker($worker_name)
 {
     // 创建子进程
     $pid = pcntl_fork();
     // 先处理收到的信号
     pcntl_signal_dispatch();
     // 父进程
     if ($pid > 0) {
         // 初始化master的一些东东
         self::$workerPidMap[$worker_name][$pid] = $pid;
         // 更新进程信息到共享内存
         self::updateStatusToShm();
         return $pid;
     } elseif ($pid === 0) {
         // 忽略信号
         self::ignoreSignal();
         // 清空任务
         Lib\Task::delAll();
         // 关闭不用的监听socket
         foreach (self::$listenedSocketsArray as $tmp_worker_name => $tmp_socket) {
             if ($tmp_worker_name != $worker_name) {
                 fclose($tmp_socket);
             }
         }
         // 尝试以指定用户运行worker进程
         if ($worker_user = Lib\Config::get($worker_name . '.user')) {
             self::setProcUser($worker_user);
         }
         // 关闭输出
         self::resetStdFd(Lib\Config::get($worker_name . '.no_debug'));
         // 尝试设置子进程进程名称
         self::setWorkerProcTitle($worker_name);
         // 包含必要文件
         require_once WORKERMAN_ROOT_DIR . 'Core/SocketWorker.php';
         // 查找worker文件
         $worker_file = \Man\Core\Lib\Config::get($worker_name . '.worker_file');
         $class_name = basename($worker_file, '.php');
         // 如果有语法错误 sleep 5秒 避免狂刷日志
         if (\Man\Core\Lib\Checker::checkSyntaxError($worker_file, $class_name)) {
             sleep(5);
         }
         require_once $worker_file;
         // 创建实例
         $worker = new $class_name($worker_name);
         // 如果该worker有配置监听端口,则将监听端口的socket传递给子进程
         if (isset(self::$listenedSocketsArray[$worker_name])) {
             $worker->setListendSocket(self::$listenedSocketsArray[$worker_name]);
         }
         // 使worker开始服务
         $worker->start();
         return 0;
     } else {
         self::notice("create worker fail worker_name:{$worker_name} detail:pcntl_fork fail");
         return $pid;
     }
 }
Ejemplo n.º 2
0
 /**
  * 创建一个worker进程
  * @param string $worker_name worker的名称
  * @return int 父进程:>0得到新worker的pid ;<0 出错; 子进程:始终为0
  */
 protected static function forkOneWorker($worker_name)
 {
     // 创建子进程
     $pid = pcntl_fork();
     // 先处理收到的信号
     pcntl_signal_dispatch();
     // 父进程
     if ($pid > 0) {
         // 初始化master的一些东东
         self::$workerPids[$worker_name][$pid] = $pid;
         // 更新进程信息到共享内存
         self::updateStatusToShm();
         return $pid;
     } elseif ($pid === 0) {
         // 忽略信号
         self::ignoreSignal();
         // 清空任务
         Lib\Task::delAll();
         // 关闭不用的监听socket
         foreach (self::$listenedSockets as $tmp_worker_name => $tmp_socket) {
             if ($tmp_worker_name != $worker_name) {
                 fclose($tmp_socket);
             }
         }
         // 尝试以指定用户运行worker
         if ($worker_user = Lib\Config::get($worker_name . '.user')) {
             self::setWorkerUser($worker_user);
         }
         // 关闭输出
         self::resetStdFd();
         // 尝试设置子进程进程名称
         self::setWorkerProcessTitle($worker_name);
         // 查找worker文件
         if ($worker_file = \Man\Core\Lib\Config::get($worker_name . '.worker_file')) {
             include_once $worker_file;
             $class_name = basename($worker_file, '.php');
         } else {
             $class_name = $worker_name;
             include_once WORKERMAN_ROOT_DIR . "workers/{$worker_name}.php";
         }
         // 创建实例
         $worker = new $class_name($worker_name);
         // 如果该worker有配置监听端口,则将监听端口的socket传递给子进程
         if (isset(self::$listenedSockets[$worker_name])) {
             $worker->setListendSocket(self::$listenedSockets[$worker_name]);
         }
         // 使worker开始服务
         $worker->start();
         return 0;
     } else {
         self::notice("create worker fail worker_name:{$worker_name} detail:pcntl_fork fail");
         return $pid;
     }
 }