Curl和pcntl_fork() [英] Curl and pcntl_fork()

查看:201
本文介绍了Curl和pcntl_fork()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些代码用于检查网站上的链接,并试图使其线程化,代码更新为使用pcntl_fork()。

I have some code that is used to check links on a website and in trying to make it "threaded", the code was updated to use pcntl_fork().

父代码适用于SSL和非SSL URL,但子代码仅适用于非SSL URL。我已经在代码中注意到了它的工作原理和它不在哪里。

The parent code is working for SSL and non-SSL URL's but the child code is only working for non-SSL URL's. I've noted in the code where it works and where it doesn't.

这里是我的fork代码。我知道下面的代码将永远循环,我已经取出循环控制代码,以便更可读。

Here is my fork code. I know the code below will loop forever, I have taken out the loop control code so it is more readable.

$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()中的代码:

As you can see, I had to open and close the database connection so it would work and I am doing the same with CURL. Here is the code in 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请求将失败。这是服务器设置的问题,而不是我可以更改。

I am using CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST because without it my SSL CURL requests will fail. It's an issue with the server set up and not something I can change.

当孩子CURL的SSL URL,我认为它失败,因为有一个问题,选项,但我不知道。如果我设置CURL为verbose,我看到以下错误:

Wwhen a child CURL's an SSL URL, I think it fails because there is a problem with setting these options, but I don't know. If I set CURL to be verbose, I see the following error:

* 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

请让我知道我可以做什么使这项工作。 / p>

Please let me know what I can do to make this work.

推荐答案

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

After a lot of research, I uncovered that the issue is not a new and is a problem with php's implementation of CURL. These other questions helped me to come up with the solution I've shared below:

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

我最后做的是使用pcntl_exec,用所提供的命令替换当前的子进程。

What I ended up doing was to use pcntl_exec which replaces the current child process with the command provided.

$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;
  }
}

这篇关于Curl和pcntl_fork()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆