微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PHP-卷毛和pcntl_fork()

我有一些代码用于检查网站上的链接,并尝试使其变为“线程化”,该代码已更新为使用pcntl_fork().

代码适用于SSL和非SSL URL,而子代码仅适用于非SSL URL.我在代码中指出了它在哪里工作,在哪里不工作.

这是我的fork代码.我知道下面的代码将永远循环,我已经取出了循环控制代码,因此更具可读性.

$this->initialize_curl();
$this->connect_database();

// prime the queue
$this->add_url_to_queue($this->source_url, 0, 0);
$this->process_next_url_in_queue($this->get_next_url_in_queue());

// SSL and non-SSL work at this point

// loop until we have processed all URL's
while (1) {
  $url = $this->get_next_url_in_queue();

  // disconnect from the database before forking since we don't want to
  // share the database connection with child processes - the first one
  // will close it and ruin the fun for the other children.
  curl_close($this->ch);
  $this->db->close();

  // create child
  $pid = pcntl_fork();

  // handle forked processing
  switch ($pid) {

    // error
    case -1:
      print "Could not fork\n";
      exit;

    // child
    case 0:

      // seperate database and curl for the child
      $this->connect_database();
      $this->initialize_curl();

      // process the url
      $this->process_next_url_in_queue($url);

      // only non-SSL works at this point

      exit;

    // parent
    default:

      // seperate database and curl for the parent
      $this->connect_database();
      $this->initialize_curl();
      break;
  }
}

如您所见,我必须打开和关闭数据库连接,这样它才能正常工作,并且我对CURL也是如此.这是initialize_curl()中的代码

$this->ch = curl_init();
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, FALSE);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($this->ch, CURLOPT_HEADER,         FALSE);

我正在使用CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST,因为如果没有它,我的SSL CURL请求将失败.这是服务器设置的问题,不是我可以更改的问题.

当儿童CURL是SSL URL时,我认为它会失败,因为设置这些选项存在问题,但我不知道.如果我将CURL设置为冗长,则会看到以下错误

* About to connect() to HOST port 443 (#0)
*   Trying IP... * connected
* Connected to HOST (IP) port 443 (#0)
* NSS error -8023
* Closing connection #0
* SSL connect error

请让我知道我可以做些什么.

解决方法:

经过大量研究,我发现这个问题不是新问题,而是PHP的CURL实现问题.这些其他问题帮助我提出了下面共享的解决方案:

> SSL Requests made with cURL fail after process fork
> libCurl SSL error after fork()

我最终要做的是使用pcntl_exec,它使用提供的命令替换了当前的子进程.

$this->initialize_curl();
$this->connect_database();

// prime the queue
$this->add_url_to_queue($this->source_url, 0, 0);
$this->process_next_url_in_queue($this->get_next_url_in_queue());

// loop until we have processed all URL's
while (1) {
  $url = $this->get_next_url_in_queue();

  // disconnect from the database before forking since we don't want to
  // share the database connection with child processes - the first one
  // will close it and ruin the fun for the other children.
  curl_close($this->ch);
  $this->db->close();

  // create child
  $pid = pcntl_fork();

  // handle forked processing
  switch ($pid) {

    // error
    case -1:
      print "Could not fork\n";
      exit;

    // child
    case 0:

      // seperate database and curl for the child
      $this->connect_database();
      $this->initialize_curl();

      // process the url
      pcntl_exec('process_next_url_in_queue.PHP', array($url));

      exit;

    // parent
    default:

      // seperate database and curl for the parent
      $this->connect_database();
      $this->initialize_curl();
      break;
  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐