Exemplo n.º 1
0
 /**
  * 创建一个子进程
  * @param Worker $worker
  * @throws Exception
  */
 public function fork_one_task($taskid)
 {
     $pid = pcntl_fork();
     // 主进程记录子进程pid
     if ($pid > 0) {
         // 暂时没用
         self::$taskpids[$taskid] = $pid;
     } elseif (0 === $pid) {
         log::warn("Fork children task({$taskid}) successful...\n");
         self::$time_start = microtime(true);
         self::$taskid = $taskid;
         self::$taskpid = posix_getpid();
         self::$taskmaster = false;
         self::$collect_succ = 0;
         self::$collect_fail = 0;
         while ($this->queue_lsize()) {
             // 如果队列中的网页比任务数多,子任务可以采集
             if ($this->queue_lsize() > self::$tasknum * 2) {
                 // 抓取页面
                 $this->collect_page();
             } else {
                 log::warn("Task(" . self::$taskid . ") waiting...\n");
                 sleep(1);
             }
             // 每采集成功一个页面,生成当前进程状态到文件,供主进程使用
             $mem = round(memory_get_usage(true) / (1024 * 1024), 2) . "MB";
             $use_time = microtime(true) - self::$time_start;
             $speed = round((self::$collect_succ + self::$collect_fail) / $use_time, 2) . "/s";
             $status = array('id' => self::$taskid, 'pid' => self::$taskpid, 'mem' => $mem, 'collect_succ' => self::$collect_succ, 'collect_fail' => self::$collect_fail, 'speed' => $speed);
             util::put_file(PATH_DATA . "/status/" . self::$taskid, json_encode($status));
         }
         // 这里用0表示正常退出
         exit(0);
     } else {
         log::error("Fork children task({$i}) fail...\n");
         exit;
     }
 }