如何在PHP中pcntl_fork工作?(How does pcntl_fork work in P

2019-06-25 03:40发布

我感到困惑pcntl_fork在PHP。

我认为它的多线程,但它是如何工作的,我怎么会在脚本中使用它?

Answer 1:

PCNTL不能使线程。 它唯一的“叉”当前的PHP的过程。 这是什么意思? 当你调用pcntl_fork()当前进程被分为两个过程。 父进程的整体命名空间被复制到子和两个过程继续只用一个差执行并行: pcntl_fork()返回的孩子的父母在PID和0中的孩子。

一些提示:

  • 它默认为禁用。 如果你成功地启用它,然后实现它仅用于CLI。 永远不要与Web服务器使用它! 它会表现在非确定性的方式。 它也能带来整机下来。 请禁用它并阅读。
  • 进程之间的通信是可能的但可怕(通过在共享存储器中序列化的对象)。
  • 文件描述符(和数据库连接)是共享的,这往往会导致问题。 你有分叉后重新连接您的数据库 ,否则你会得到这样的错误MySQL server has gone away所有派生进程时,他们的第一个关闭连接。
  • 父进程必须等待孩子完成,否则将留下僵尸进程消耗系统资源后面。

这里的例子,从文档 :

<?php

$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
} else if ($pid) {
     // we are the parent
     pcntl_wait($status); //Protect against Zombie children
} else {
     // we are the child
}

但要记住,PHP只是脚本语言。 它不是专为并行计算。 你可以在更低级别的语言,同时运行CRONs,消息队列或程序做的更好的工作,根据您的需要。

分叉的PHP程序是非常难以阅读,理解和调试。 保持该计划将是一场噩梦。

不要犯错,避免分叉。 你不需要它。 你真正需要的是异步任务运行。 好消息,还有的RabbitMQ和不错的教程 ;-)你也可以试着叫有前途的RabbitMQ库兔子

PS:使用消息队列,而不是分叉为您提供了一个更具有优势。 您可以处理队列中的多台服务器和流量的增长水平扩展。

编辑2019年3月7日

我已经打了很多与异步并行框架amphp ,我要在这里提到它。 如果你真的需要在单个请求运行异步非阻塞的任务,我认为amphp是今天的最佳解决方案。 它使用PHP发电机的概念( $value = yield $promise )无reactphp般的地狱承诺执行人类可读的代码。

https://amphp.org/



文章来源: How does pcntl_fork work in PHP?
标签: php fork pcntl